用Suno创作一首属于自己的歌曲:从零到精通完全指南

1. Suno AI音乐创作全景图

1.1 Suno核心技术解析

graph TB
    A[Suno AI音乐创作平台] --> B[输入层]
    A --> C[处理层]
    A --> D[输出层]
    
    B --> B1[文本提示]
    B --> B2[旋律哼唱]
    B --> B3[风格参考]
    B --> B4[情绪设定]
    
    C --> C1[歌词生成]
    C --> C2[旋律创作]
    C --> C3[和声编排]
    C --> C4[乐器配器]
    
    D --> D1[完整歌曲]
    D --> D2[多版本]
    D --> D3[音轨分离]
    D --> D4[格式导出]

1.2 平台特性与限制对比

特性 Suno v3 Suno Chirp 竞品对比
歌曲长度 1-3分钟 30-60秒 同水平
音质 CD级 良好 行业领先
风格支持 100+种 50+种 最丰富
人声质量 真人级 良好 业界最佳
自定义度 最高
API支持 部分有
成本 $10-30/月 免费有限 中等

2. 入门篇:5分钟创作第一首歌

2.1 Suno Web端快速上手

# suno_quickstart.py
"""
Suno AI音乐创作快速入门脚本
通过API创建你的第一首AI歌曲
"""

import requests
import json
import time
import os
from pathlib import Path
from dotenv import load_dotenv
from typing import Dict, List, Optional, Tuple
import base64

class SunoMusicCreator:
    """Suno音乐创作器"""
    
    def __init__(self, api_key=None, session_id=None):
        # 加载环境变量
        load_dotenv()
        self.api_key = api_key or os.getenv('SUNO_API_KEY')
        self.session_id = session_id or os.getenv('SUNO_SESSION_ID')
        
        if not self.api_key and not self.session_id:
            print("⚠️  警告:未设置API密钥或Session ID,部分功能可能受限")
        
        # API配置
        self.base_url = "https://api.suno.ai"
        self.headers = {
            "Authorization": f"Bearer {self.api_key}" if self.api_key else "",
            "Content-Type": "application/json"
        }
        
        # 浏览器模式(无需API)
        self.browser_mode = not self.api_key
        if self.browser_mode:
            print("🔍 使用浏览器模式(需要手动操作)")
        
        # 创建目录
        self.output_dir = Path("suno_music")
        self.output_dir.mkdir(exist_ok=True)
        
        # 风格库
        self.genre_library = {
            "流行": ["pop", "流行", "朗朗上口", "电台热门"],
            "摇滚": ["rock", "摇滚", "吉他", "鼓点强劲"],
            "民谣": ["acoustic", "民谣", "吉他弹唱", "抒情"],
            "嘻哈": ["hiphop", "嘻哈", "说唱", "节奏感强"],
            "电子": ["electronic", "电子", "EDM", "合成器"],
            "R&B": ["rnb", "节奏布鲁斯", "灵魂乐", "抒情"],
            "爵士": ["jazz", "爵士", "萨克斯", "即兴"],
            "古典": ["classical", "古典", "交响", "钢琴"],
            "国风": ["chinese traditional", "国风", "古风", "中国风"],
            "乡村": ["country", "乡村", "吉他", "田园"]
        }
        
        # 情绪库
        self.mood_library = {
            "快乐": ["happy", "欢快", "兴奋", "正能量"],
            "悲伤": ["sad", "悲伤", "忧郁", "抒情"],
            "浪漫": ["romantic", "浪漫", "爱情", "温柔"],
            "励志": ["inspiring", "励志", "振奋", "力量"],
            "放松": ["relaxing", "放松", "舒缓", "平静"],
            "激情": ["energetic", "激情", "动感", "活力"],
            "神秘": ["mysterious", "神秘", "悬疑", "奇幻"],
            "怀旧": ["nostalgic", "怀旧", "复古", "回忆"]
        }
        
        print("🎵 Suno音乐创作器初始化完成")
    
    def create_song_from_prompt(self, prompt: str, make_instrumental: bool = False,
                               custom_mode: bool = False, **kwargs) -> Optional[Dict]:
        """从提示词创建歌曲"""
        
        print(f"🎶 正在创作歌曲: '{prompt[:50]}...'")
        
        if self.browser_mode:
            print("🌐 浏览器模式:请手动操作")
            print(f"提示词: {prompt}")
            return self._browser_mode_instructions(prompt, **kwargs)
        
        # 构建API请求
        data = {
            "prompt": prompt,
            "make_instrumental": make_instrumental,
            "wait_audio": kwargs.get("wait_audio", True)
        }
        
        # 自定义模式参数
        if custom_mode:
            data.update({
                "title": kwargs.get("title", ""),
                "tags": kwargs.get("tags", ""),
                "mv": kwargs.get("mv", "chirp-v3-5"),
                "continue_at": kwargs.get("continue_at", None),
                "continue_clip_id": kwargs.get("continue_clip_id", None)
            })
        
        try:
            # 发送生成请求
            endpoint = "/api/generate/v2/" if custom_mode else "/api/generate"
            response = requests.post(
                f"{self.base_url}{endpoint}",
                headers=self.headers,
                json=data,
                timeout=60
            )
            
            if response.status_code == 200:
                result = response.json()
                
                if custom_mode:
                    clips = result.get("clips", [])
                    if clips:
                        clip_id = clips[0]["id"]
                        print(f"📤 歌曲任务已提交,Clip ID: {clip_id}")
                        
                        # 轮询状态
                        audio_url = self._poll_clip_status(clip_id)
                        
                        if audio_url:
                            # 下载音频
                            audio_path = self._download_audio(audio_url, prompt)
                            return {
                                "clip_id": clip_id,
                                "audio_url": audio_url,
                                "audio_path": audio_path,
                                "prompt": prompt
                            }
                else:
                    # v2模式
                    clip_ids = result.get("id", [])
                    if clip_ids:
                        print(f"📤 生成任务已提交,ID: {clip_ids[0]}")
                        # 这里需要轮询获取结果
                        # 简化处理,返回任务ID
                        return {"task_id": clip_ids[0], "prompt": prompt}
                
                return None
                
            else:
                print(f"❌ API请求失败: {response.status_code}")
                print(f"响应: {response.text}")
                return None
                
        except Exception as e:
            print(f"❌ 请求过程中出错: {str(e)}")
            return None
    
    def generate_with_lyrics(self, title: str, lyrics: str, genre: str = "流行",
                            mood: str = "快乐", **kwargs) -> Optional[Dict]:
        """使用自定义歌词生成歌曲"""
        
        # 构建提示词
        prompt = self._build_lyrics_prompt(title, lyrics, genre, mood)
        
        print(f"📝 使用自定义歌词生成歌曲: '{title}'")
        print(f"🎵 风格: {genre}, 情绪: {mood}")
        print(f"📄 歌词行数: {len(lyrics.splitlines())}")
        
        return self.create_song_from_prompt(prompt, **kwargs)
    
    def create_song_series(self, theme: str, num_songs: int = 3, 
                          genres: List[str] = None) -> List[Dict]:
        """创建主题系列歌曲"""
        
        if genres is None:
            genres = ["流行", "民谣", "电子"]
        
        results = []
        
        print(f"\n{'='*60}")
        print(f"🎼 开始创作系列歌曲: {theme}")
        print(f"📊 数量: {num_songs}, 风格: {', '.join(genres)}")
        print(f"{'='*60}\n")
        
        for i in range(num_songs):
            genre = genres[i % len(genres)]
            mood = self._get_series_mood(theme, i, num_songs)
            
            # 生成歌曲标题
            title = self._generate_song_title(theme, genre, mood, i+1)
            
            # 生成歌词
            lyrics = self._generate_lyrics_for_theme(theme, genre, mood)
            
            print(f"\n▶️ 创作第 {i+1}/{num_songs} 首歌曲")
            print(f"  标题: {title}")
            print(f"  风格: {genre}, 情绪: {mood}")
            
            result = self.generate_with_lyrics(
                title=title,
                lyrics=lyrics,
                genre=genre,
                mood=mood,
                wait_audio=True
            )
            
            if result:
                result.update({
                    "song_number": i+1,
                    "title": title,
                    "genre": genre,
                    "mood": mood,
                    "lyrics_preview": lyrics[:100] + "..." if len(lyrics) > 100 else lyrics
                })
                results.append(result)
            
            # 避免API限流
            if i < num_songs - 1:
                print("⏸️  等待25秒继续下一首...")
                time.sleep(25)
        
        # 生成系列报告
        self._generate_series_report(results, theme)
        
        return results
    
    def _build_lyrics_prompt(self, title: str, lyrics: str, genre: str, mood: str) -> str:
        """构建歌词提示词"""
        
        # 获取风格关键词
        genre_keywords = self.genre_library.get(genre, ["pop"])
        mood_keywords = self.mood_library.get(mood, ["happy"])
        
        prompt = f"歌曲标题:{title}\n\n"
        prompt += f"风格:{genre}{', '.join(genre_keywords)}\n"
        prompt += f"情绪:{mood}{', '.join(mood_keywords)}\n\n"
        prompt += "歌词:\n"
        prompt += lyrics + "\n\n"
        prompt += "请为以上歌词创作一首完整的歌曲,包含主歌、副歌、桥段等结构,"
        prompt += "确保旋律优美,节奏与情绪匹配。"
        
        return prompt
    
    def _generate_song_title(self, theme: str, genre: str, mood: str, number: int) -> str:
        """生成歌曲标题"""
        
        # 根据主题、风格、情绪生成标题
        titles = {
            "爱情": ["心动时刻", "永恒誓言", "相思成海", "爱如初见"],
            "友情": ["并肩同行", "青春纪念册", "友谊万岁", "最好的我们"],
            "梦想": ["追光者", "星辰大海", "破晓时分", "勇往直前"],
            "自然": ["风之诗", "山川入梦", "四季之歌", "听雨"],
            "城市": ["霓虹之下", "地铁末班车", "城市之光", "夜未央"]
        }
        
        # 尝试匹配主题
        for key, title_list in titles.items():
            if key in theme:
                return f"{title_list[(number-1) % len(title_list)]} - {theme}"
        
        # 默认标题
        default_titles = [
            f"{theme}之歌",
            f"关于{theme}",
            f"{theme}的旋律",
            f"{theme}幻想曲"
        ]
        
        return default_titles[(number-1) % len(default_titles)]
    
    def _generate_lyrics_for_theme(self, theme: str, genre: str, mood: str) -> str:
        """为主题生成歌词"""
        
        # 歌词模板
        templates = {
            "流行": {
                "结构": ["主歌A", "副歌", "主歌B", "副歌", "桥段", "副歌"],
                "押韵": "AABB"
            },
            "民谣": {
                "结构": ["主歌A", "主歌B", "副歌", "主歌C", "副歌"],
                "押韵": "ABAB"
            },
            "摇滚": {
                "结构": ["主歌", "副歌", "吉他独奏", "主歌", "副歌"],
                "押韵": "自由"
            },
            "嘻哈": {
                "结构": ["Intro", "Verse 1", "Hook", "Verse 2", "Hook", "Outro"],
                "押韵": "多押"
            }
        }
        
        template = templates.get(genre, templates["流行"])
        
        # 根据主题和情绪生成歌词内容
        lyric_lines = []
        
        if "快乐" in mood or "兴奋" in mood:
            lyric_lines.extend([
                f"阳光洒满每个角落",
                f"心中的快乐在唱歌",
                f"让我们一起跳起舞",
                f"忘记所有烦恼忧愁"
            ])
        elif "悲伤" in mood or "忧郁" in mood:
            lyric_lines.extend([
                f"雨滴轻轻敲打窗棂",
                f"回忆在夜色中蔓延",
                f"逝去的时光不再回",
                f"只留下思念的旋律"
            ])
        elif "浪漫" in mood:
            lyric_lines.extend([
                f"星光点亮你的眼眸",
                f"温柔在指尖轻轻流",
                f"这一刻仿佛成永恒",
                f"爱在心跳声中绽放"
            ])
        else:
            lyric_lines.extend([
                f"追寻着远方的梦想",
                f"脚步不停向前方",
                f"即使风雨阻挡路途",
                f"心中的火焰永不灭"
            ])
        
        # 构建完整歌词
        lyrics = ""
        section_labels = template["结构"]
        
        for i, section in enumerate(section_labels):
            lyrics += f"[{section}]\n"
            
            # 每个部分2-4行
            lines_in_section = 4 if "副歌" in section else 2
            start_idx = (i * 2) % len(lyric_lines)
            
            for j in range(lines_in_section):
                line_idx = (start_idx + j) % len(lyric_lines)
                lyrics += lyric_lines[line_idx] + "\n"
            
            lyrics += "\n"
        
        return lyrics.strip()
    
    def _get_series_mood(self, theme: str, index: int, total: int) -> str:
        """获取系列歌曲情绪"""
        
        # 根据位置决定情绪变化
        moods = ["快乐", "浪漫", "励志", "怀旧", "放松"]
        
        if "爱情" in theme:
            mood_sequence = ["浪漫", "快乐", "悲伤", "怀旧"]
        elif "梦想" in theme:
            mood_sequence = ["励志", "激情", "快乐", "放松"]
        elif "自然" in theme:
            mood_sequence = ["放松", "神秘", "快乐", "怀旧"]
        else:
            mood_sequence = moods
        
        return mood_sequence[index % len(mood_sequence)]
    
    def _poll_clip_status(self, clip_id: str, max_attempts: int = 30) -> Optional[str]:
        """轮询Clip状态"""
        print("⏳ 等待音频生成...", end="", flush=True)
        
        for attempt in range(max_attempts):
            time.sleep(10)  # Suno通常需要30-90秒
            
            try:
                status_response = requests.get(
                    f"{self.base_url}/api/clip/{clip_id}",
                    headers=self.headers,
                    timeout=10
                )
                
                if status_response.status_code == 200:
                    status_data = status_response.json()
                    status = status_data.get("status")
                    
                    print(".", end="", flush=True)
                    
                    if status == "complete":
                        print("\n✅ 音频生成完成!")
                        return status_data.get("audio_url")
                    elif status == "failed":
                        print(f"\n❌ 生成失败")
                        return None
                    # 继续等待...
                else:
                    print(f"\n⚠️ 状态查询失败: {status_response.status_code}")
            
            except Exception as e:
                print(f"\n⚠️ 状态查询异常: {str(e)}")
        
        print(f"\n❌ 生成超时({max_attempts * 10}秒)")
        return None
    
    def _download_audio(self, audio_url: str, prompt: str) -> Optional[Path]:
        """下载音频文件"""
        try:
            # 生成文件名
            timestamp = time.strftime("%Y%m%d_%H%M%S")
            safe_prompt = "".join(c for c in prompt[:30] if c.isalnum() or c in (' ', '-', '_')).rstrip()
            filename = f"{timestamp}_{safe_prompt}.mp3"
            filepath = self.output_dir / filename
            
            # 下载音频
            print(f"⬇️ 下载音频到: {filepath}")
            
            response = requests.get(audio_url, stream=True, timeout=30)
            
            if response.status_code == 200:
                total_size = int(response.headers.get('content-length', 0))
                downloaded = 0
                
                with open(filepath, 'wb') as f:
                    for chunk in response.iter_content(chunk_size=8192):
                        f.write(chunk)
                        downloaded += len(chunk)
                        
                        # 显示进度
                        if total_size > 0:
                            percent = downloaded / total_size * 100
                            print(f"\r下载进度: {percent:.1f}%", end="", flush=True)
                
                print(f"\n✅ 下载完成!大小: {filepath.stat().st_size / 1024:.1f} KB")
                return filepath
            else:
                print(f"❌ 下载失败: {response.status_code}")
                return None
                
        except Exception as e:
            print(f"❌ 下载过程中出错: {str(e)}")
            return None
    
    def _browser_mode_instructions(self, prompt: str, **kwargs) -> Dict:
        """浏览器模式操作指南"""
        
        instructions = f"""
        🌐 浏览器模式操作指南
        ====================
        
        由于未设置API密钥,请按以下步骤手动操作:
        
        1. 访问 https://suno.com
        2. 登录您的Suno账户
        3. 点击"Create"或"生成"按钮
        4. 在提示词框中输入:
        
        {prompt}
        
        5. 选择参数:
           - 风格: {kwargs.get('style', '默认')}
           - 长度: {kwargs.get('duration', '2分钟')}
           - 乐器: {kwargs.get('instrumental', False)}
        
        6. 点击"Generate"开始创作
        7. 等待1-3分钟生成完成
        8. 下载生成的音频文件
        
        完成后,请将文件保存到: {self.output_dir.absolute()}/
        """
        
        print(instructions)
        
        # 创建说明文件
        instructions_file = self.output_dir / "browser_instructions.txt"
        with open(instructions_file, 'w', encoding='utf-8') as f:
            f.write(instructions)
        
        return {
            "mode": "browser",
            "instructions_file": str(instructions_file),
            "prompt": prompt
        }
    
    def _generate_series_report(self, results: List[Dict], theme: str):
        """生成系列歌曲报告"""
        report_path = self.output_dir / f"{theme}_series_report.md"
        
        with open(report_path, 'w', encoding='utf-8') as f:
            f.write(f"# 系列歌曲创作报告: {theme}\n\n")
            f.write(f"生成时间: {time.strftime('%Y-%m-%d %H:%M:%S')}\n\n")
            
            # 统计信息
            success_count = sum(1 for r in results if r.get('audio_path'))
            total_count = len(results)
            
            f.write("## 📊 统计信息\n")
            f.write(f"- 计划创作: {total_count} 首\n")
            f.write(f"- 成功创作: {success_count} 首\n")
            f.write(f"- 成功率: {success_count/total_count*100:.1f}%\n\n")
            
            # 详细结果
            f.write("## 🎵 歌曲列表\n\n")
            
            for i, result in enumerate(results, 1):
                song_number = result.get('song_number', i)
                title = result.get('title', f'歌曲{song_number}')
                genre = result.get('genre', '未知')
                mood = result.get('mood', '未知')
                
                if result.get('audio_path'):
                    status_icon = "✅"
                    file_info = f"文件: `{Path(result['audio_path']).name}`"
                else:
                    status_icon = "❌"
                    file_info = "状态: 生成失败"
                
                f.write(f"### {status_icon}{song_number}首: {title}\n")
                f.write(f"- **风格**: {genre}\n")
                f.write(f"- **情绪**: {mood}\n")
                f.write(f"- **歌词预览**: {result.get('lyrics_preview', '')}\n")
                f.write(f"- **{file_info}**\n\n")
            
            # 创作建议
            f.write("## 💡 创作建议\n\n")
            
            if success_count == total_count:
                f.write("✅ 系列创作非常成功!建议:\n")
                f.write("1. 考虑制作专辑封面\n")
                f.write("2. 为歌曲添加介绍文案\n")
                f.write("3. 发布到音乐平台\n")
            elif success_count >= total_count * 0.7:
                f.write("👍 大部分歌曲创作成功,建议:\n")
                f.write("1. 重新尝试失败的几首\n")
                f.write("2. 调整提示词参数\n")
                f.write("3. 检查网络连接\n")
            else:
                f.write("⚠️  创作成功率较低,建议:\n")
                f.write("1. 简化提示词\n")
                f.write("2. 缩短歌曲长度\n")
                f.write("3. 使用更常见的风格\n")
                f.write("4. 检查API配额\n")
        
        print(f"📊 系列报告已生成: {report_path}")

# 使用示例
if __name__ == "__main__":
    # 初始化创作器
    creator = SunoMusicCreator()
    
    # 示例1: 简单提示词创作
    print("示例1: 使用提示词创作歌曲")
    prompt = "创作一首关于夏天的流行歌曲,欢快节奏,有海浪声和海鸥叫声,副歌朗朗上口"
    
    result = creator.create_song_from_prompt(prompt, wait_audio=True)
    
    if result and result.get('audio_path'):
        print(f"🎉 歌曲创作成功: {result['audio_path']}")
    
    # 示例2: 自定义歌词创作
    print("\n示例2: 使用自定义歌词创作")
    
    custom_lyrics = """
    [主歌]
    清晨的阳光洒在脸上
    新的一天开始了旅程
    微风轻拂发梢的时候
    心中充满希望的光芒
    
    [副歌]
    向前走,不回头
    梦想在远方招手
    每一步,都坚定
    勇敢追求心中的自由
    
    [主歌]
    路上的风景虽然曲折
    但每一步都值得珍藏
    那些汗水浇灌的时光
    终将开出最美的花朵
    
    [副歌]
    向前走,不回头
    梦想在远方招手
    每一步,都坚定
    勇敢追求心中的自由
    """
    
    result = creator.generate_with_lyrics(
        title="勇敢前行",
        lyrics=custom_lyrics,
        genre="流行",
        mood="励志",
        wait_audio=True
    )
    
    if result and result.get('audio_path'):
        print(f"🎉 自定义歌曲创作成功: {result['audio_path']}")
    
    # 示例3: 创作系列歌曲
    print("\n示例3: 创作爱情主题系列歌曲")
    
    series_results = creator.create_song_series(
        theme="爱情旅程",
        num_songs=4,
        genres=["流行", "民谣", "R&B", "电子"]
    )
    
    print(f"\n系列创作完成!成功 {len([r for r in series_results if r.get('audio_path')])} 首")

2.2 环境配置与访问方式

# Suno AI音乐创作环境配置指南

## 第一步:获取访问权限

### 方案A:官方Web端(推荐新手)
1. 访问 https://suno.com
2. 使用Google账号或邮箱注册
3. 每日免费额度:10 credits(约5-10首歌)
4. 升级计划:$10-30/月(无限生成)

### 方案B:API访问(开发者)
1. 访问 https://suno.com/api
2. 申请API访问权限(可能需要等待)
3. 获取API密钥
4. 查看文档和限制

### 方案C:Discord Bot(社区版)
1. 加入Suno Discord: https://discord.gg/suno
2. 在#music-generation频道使用命令
3. 免费但有排队限制

## 第二步:本地环境配置

```bash
# 1. 安装Python 3.8+
python --version

# 2. 创建虚拟环境
python -m venv suno-music

# 3. 激活虚拟环境
# Windows:
suno-music\Scripts\activate
# Mac/Linux:
source suno-music/bin/activate

# 4. 安装依赖包
pip install requests python-dotenv pandas openai

# 5. 创建环境变量文件
cat > .env << EOF
# Suno配置
SUNO_API_KEY=your_suno_api_key_here
SUNO_SESSION_ID=your_session_cookie_here  # 可选

# OpenAI配置(用于歌词生成)
OPENAI_API_KEY=your_openai_key_here

# 项目配置
DEFAULT_GENRE=pop
DEFAULT_MOOD=happy
OUTPUT_FORMAT=mp3
EOF

# 6. 创建项目结构
mkdir -p suno_music/{songs,lyrics,projects}
mkdir -p assets/{covers,templates}
mkdir -p scripts/{generators,processors}

第三步:快速测试

# test_suno_access.py
import os
from dotenv import load_dotenv

def test_suno_environment():
    load_dotenv()
    
    print("🔍 Suno音乐创作环境测试")
    print("="*50)
    
    # 检查关键配置
    configs = {
        "SUNO_API_KEY": "Suno API密钥",
        "OPENAI_API_KEY": "OpenAI密钥(歌词生成)",
        "DEFAULT_GENRE": "默认音乐风格"
    }
    
    for env_key, description in configs.items():
        value = os.getenv(env_key)
        if value:
            print(f"✅ {description}: 已设置")
        else:
            print(f"⚠️  {description}: 未设置(部分功能受限)")
    
    # 检查目录
    import os.path as op
    directories = ['suno_music', 'assets', 'scripts']
    for dir_name in directories:
        if op.exists(dir_name):
            print(f"✅ 目录 '{dir_name}': 存在")
        else:
            print(f"❌ 目录 '{dir_name}': 不存在")
    
    print("="*50)
    print("🎵 测试完成!开始你的音乐创作之旅吧!")

if __name__ == "__main__":
    test_suno_environment()

第四步:Web端快速上手

1. 基本操作流程:

  1. 访问 https://suno.com 并登录
  2. 点击"Create"按钮
  3. 在文本框中输入你的想法
  4. 选择风格参数
  5. 点击"Generate"
  6. 等待1-3分钟生成
  7. 试听并下载

2. 提示词示例:

  • 中文:创作一首关于春天的民谣,吉他伴奏,温暖治愈
  • 英文:Create a pop song about summer love with catchy chorus
  • 混合:Make a Chinese traditional style song with erhu and piano

3. 实用技巧:

  • 使用具体形容词:明亮、温柔、激情、梦幻
  • 指定乐器:钢琴、吉他、鼓、合成器
  • 描述场景:雨中漫步、星空下、城市夜晚
  • 设定情绪:快乐、悲伤、浪漫、励志

## 3. 进阶篇:专业音乐创作技巧

### 3.1 歌词工程与结构设计
```python
# lyrics_engineering.py
"""
专业歌词工程系统
生成结构化、有韵律的歌词
"""

import json
import random
from typing import Dict, List, Tuple, Optional
from dataclasses import dataclass
from enum import Enum

class SongStructure(Enum):
    """歌曲结构类型"""
    POP_STANDARD = "流行标准"  # 主歌-副歌-主歌-副歌-桥段-副歌
    BALLAD = "民谣"          # 主歌-主歌-副歌-主歌-副歌
    ROCK = "摇滚"            # 主歌-副歌-吉他独奏-主歌-副歌
    HIPHOP = "嘻哈"          # Intro-Verse-Hook-Verse-Hook-Outro
    EDM = "电子舞曲"         # Intro-Buildup-Drop-Bridge-Drop-Outro

class RhymeScheme(Enum):
    """押韵方案"""
    AABB = "隔行押韵"      # 行1&2押韵,行3&4押韵
    ABAB = "交叉押韵"      # 行1&3押韵,行2&4押韵
    ABBA = "环绕押韵"      # 行1&4押韵,行2&3押韵
    FREE = "自由押韵"      # 无固定规则
    MULTI = "多押"        # 嘻哈风格的多重押韵

@dataclass
class SongTheme:
    """歌曲主题"""
    name: str
    keywords: List[str]
    common_metaphors: List[str]
    emotional_range: List[str]
    typical_structure: SongStructure

class LyricEngineer:
    """歌词工程师"""
    
    def __init__(self):
        # 初始化主题库
        self.themes = self._initialize_themes()
        
        # 押韵词典(简化的中文押韵)
        self.rhyme_dict = {
            "a": ["啊", "吧", "啦", "吗", "呀", "哈"],  # a韵
            "o": ["哦", "我", "多", "火", "果", "落"],  # o韵
            "e": ["的", "了", "呢", "么", "着", "这"],  # e韵
            "i": ["你", "里", "起", "意", "气", "喜"],  # i韵
            "u": ["路", "处", "度", "木", "诉", "悟"],  # u韵
            "ai": ["爱", "来", "在", "开", "海", "带"],  # ai韵
            "ei": ["美", "飞", "倍", "泪", "谁", "为"],  # ei韵
            "ao": ["到", "好", "道", "老", "早", "宝"],  # ao韵
            "ou": ["有", "后", "手", "头", "走", "口"],  # ou韵
            "an": ["看", "难", "然", "安", "淡", "感"],  # an韵
            "en": ["人", "真", "深", "分", "门", "文"],  # en韵
            "ang": ["上", "望", "长", "伤", "光", "堂"],  # ang韵
            "eng": ["风", "声", "生", "梦", "等", "情"]   # eng韵
        }
        
        # 常用词汇库
        self.vocabulary = {
            "自然": ["阳光", "月光", "星空", "海洋", "山川", "森林", "花朵", "雨滴", "微风", "云朵"],
            "情感": ["心跳", "思念", "微笑", "泪水", "拥抱", "牵手", "回忆", "梦想", "希望", "勇气"],
            "时间": ["永远", "瞬间", "明天", "昨天", "时光", "岁月", "青春", "未来", "过去", "现在"],
            "空间": ["远方", "身旁", "心中", "世界", "角落", "天空", "大地", "旅途", "路口", "彼岸"]
        }
    
    def _initialize_themes(self) -> Dict[str, SongTheme]:
        """初始化主题库"""
        return {
            "爱情": SongTheme(
                name="爱情",
                keywords=["相遇", "相爱", "分离", "重逢", "誓言", "永恒"],
                common_metaphors=["星辰大海", "春暖花开", "雨中漫步", "心跳交响"],
                emotional_range=["甜蜜", "思念", "痛苦", "幸福", "期待"],
                typical_structure=SongStructure.POP_STANDARD
            ),
            "梦想": SongTheme(
                name="梦想", 
                keywords=["追求", "坚持", "努力", "成功", "挫折", "成长"],
                common_metaphors=["破茧成蝶", "星辰大海", "乘风破浪", "曙光初现"],
                emotional_range=["激情", "希望", "挫折", "坚持", "成就"],
                typical_structure=SongStructure.ROCK
            ),
            "友情": SongTheme(
                name="友情",
                keywords=["陪伴", "支持", "成长", "回忆", "信任", "时光"],
                common_metaphors=["并肩同行", "青春纪念", "岁月如歌", "风雨同舟"],
                emotional_range=["温暖", "怀念", "感激", "快乐", "不舍"],
                typical_structure=SongStructure.BALLAD
            ),
            "自然": SongTheme(
                name="自然",
                keywords=["四季", "风景", "生命", "宁静", "和谐", "美丽"],
                common_metaphors=["大地之歌", "风的低语", "水的流动", "山的呼吸"],
                emotional_range=["平静", "感动", "敬畏", "喜悦", "沉思"],
                typical_structure=SongStructure.BALLAD
            ),
            "城市": SongTheme(
                name="城市",
                keywords=["霓虹", "人群", "孤独", "梦想", "奋斗", "夜晚"],
                common_metaphors=["钢铁森林", "光影交错", "城市脉搏", "喧嚣中的寂静"],
                emotional_range=["孤独", "希望", "疲惫", "激情", "迷茫"],
                typical_structure=SongStructure.EDM
            )
        }
    
    def generate_structured_lyrics(self, theme_name: str, 
                                  structure: SongStructure = None,
                                  rhyme_scheme: RhymeScheme = RhymeScheme.AABB,
                                  line_length: int = 8) -> Dict:
        """生成结构化歌词"""
        
        theme = self.themes.get(theme_name)
        if not theme:
            theme = self.themes["爱情"]  # 默认主题
        
        if not structure:
            structure = theme.typical_structure
        
        print(f"🎵 生成 {theme_name} 主题歌词")
        print(f"📐 结构: {structure.value}")
        print(f"🎶 押韵: {rhyme_scheme.value}")
        
        # 根据结构生成各部分
        lyrics_structure = self._get_structure_template(structure)
        
        lyrics = {}
        total_lines = 0
        
        for section_name in lyrics_structure:
            section_lines = lyrics_structure[section_name]
            
            # 生成该部分的歌词
            section_lyrics = self._generate_section(
                theme=theme,
                section_name=section_name,
                num_lines=section_lines,
                rhyme_scheme=rhyme_scheme,
                line_length=line_length
            )
            
            lyrics[section_name] = section_lyrics
            total_lines += len(section_lyrics)
        
        # 构建完整歌词文本
        full_lyrics = self._assemble_full_lyrics(lyrics, structure)
        
        return {
            "theme": theme_name,
            "structure": structure.value,
            "rhyme_scheme": rhyme_scheme.value,
            "total_lines": total_lines,
            "sections": lyrics,
            "full_lyrics": full_lyrics,
            "analysis": self._analyze_lyrics(lyrics, theme)
        }
    
    def _get_structure_template(self, structure: SongStructure) -> Dict[str, int]:
        """获取结构模板"""
        templates = {
            SongStructure.POP_STANDARD: {
                "主歌A": 4,
                "副歌": 4,
                "主歌B": 4,
                "副歌": 4,
                "桥段": 4,
                "副歌": 4
            },
            SongStructure.BALLAD: {
                "主歌A": 4,
                "主歌B": 4,
                "副歌": 4,
                "主歌C": 4,
                "副歌": 4
            },
            SongStructure.ROCK: {
                "主歌": 4,
                "副歌": 4,
                "吉他独奏": 4,
                "主歌": 4,
                "副歌": 4
            },
            SongStructure.HIPHOP: {
                "Intro": 2,
                "Verse 1": 8,
                "Hook": 4,
                "Verse 2": 8,
                "Hook": 4,
                "Outro": 2
            },
            SongStructure.EDM: {
                "Intro": 2,
                "Buildup": 4,
                "Drop": 4,
                "Bridge": 4,
                "Drop": 4,
                "Outro": 2
            }
        }
        
        return templates.get(structure, templates[SongStructure.POP_STANDARD])
    
    def _generate_section(self, theme: SongTheme, section_name: str,
                         num_lines: int, rhyme_scheme: RhymeScheme,
                         line_length: int) -> List[str]:
        """生成一个部分的歌词"""
        
        lines = []
        
        # 根据部分类型选择词汇
        if "主歌" in section_name or "Verse" in section_name:
            vocab_categories = ["自然", "情感", "时间"]
        elif "副歌" in section_name or "Hook" in section_name:
            vocab_categories = ["情感", "时间"]
        elif "桥段" in section_name or "Bridge" in section_name:
            vocab_categories = ["空间", "情感"]
        else:
            vocab_categories = list(self.vocabulary.keys())
        
        # 生成每行歌词
        for i in range(num_lines):
            line = self._generate_line(
                theme=theme,
                vocab_categories=vocab_categories,
                line_length=line_length,
                line_number=i,
                total_lines=num_lines
            )
            lines.append(line)
        
        # 应用押韵
        if rhyme_scheme != RhymeScheme.FREE:
            lines = self._apply_rhyme_scheme(lines, rhyme_scheme)
        
        return lines
    
    def _generate_line(self, theme: SongTheme, vocab_categories: List[str],
                      line_length: int, line_number: int, 
                      total_lines: int) -> str:
        """生成单行歌词"""
        
        # 选择词汇类别
        category = random.choice(vocab_categories)
        base_words = random.sample(self.vocabulary[category], 2)
        
        # 添加主题关键词
        if random.random() > 0.5:
            keyword = random.choice(theme.keywords)
            base_words.append(keyword)
        
        # 添加比喻(在副歌部分更多使用)
        is_chorus = line_number >= total_lines * 0.3  # 假设30%后是副歌
        if is_chorus and random.random() > 0.7:
            metaphor = random.choice(theme.common_metaphors)
            base_words.append(metaphor)
        
        # 构建句子
        sentence_structures = [
            f"{base_words[0]}的{base_words[1]}",
            f"{base_words[0]}{base_words[1]}",
            f"{base_words[1]}中{base_words[0]}",
            f"{base_words[0]}{base_words[2]}的{base_words[1]}"
        ]
        
        line = random.choice(sentence_structures)
        
        # 确保长度合适
        while len(line) < line_length - 2:
            extra_word = random.choice(list(self.vocabulary.values())[0])
            line += extra_word
        
        # 截断到合适长度
        if len(line) > line_length:
            line = line[:line_length]
        
        return line
    
    def _apply_rhyme_scheme(self, lines: List[str], 
                           rhyme_scheme: RhymeScheme) -> List[str]:
        """应用押韵方案"""
        
        if rhyme_scheme == RhymeScheme.AABB:
            # 每两行押韵
            for i in range(0, len(lines), 2):
                if i + 1 < len(lines):
                    lines[i+1] = self._make_rhyme(lines[i], lines[i+1])
        
        elif rhyme_scheme == RhymeScheme.ABAB:
            # 交叉押韵
            for i in range(0, len(lines), 2):
                if i + 2 < len(lines):
                    lines[i+2] = self._make_rhyme(lines[i], lines[i+2])
        
        return lines
    
    def _make_rhyme(self, line1: str, line2: str) -> str:
        """使两行押韵"""
        
        # 提取最后1-2个字
        last_word1 = line1[-1] if len(line1) >= 1 else line1[-2:]
        
        # 寻找押韵的字
        for rhyme_group, words in self.rhyme_dict.items():
            if any(word in last_word1 for word in words[:3]):
                # 用同韵的字替换line2的最后一个字
                rhyming_word = random.choice(words)
                if len(line2) >= 1:
                    line2 = line2[:-1] + rhyming_word
                break
        
        return line2
    
    def _assemble_full_lyrics(self, sections: Dict[str, List[str]], 
                             structure: SongStructure) -> str:
        """组装完整歌词文本"""
        
        full_text = ""
        
        for section_name, lines in sections.items():
            full_text += f"[{section_name}]\n"
            
            for line in lines:
                full_text += line + "\n"
            
            full_text += "\n"
        
        return full_text.strip()
    
    def _analyze_lyrics(self, lyrics: Dict[str, List[str]], 
                       theme: SongTheme) -> Dict:
        """分析歌词质量"""
        
        total_words = 0
        unique_words = set()
        emotion_words = 0
        
        for section_lines in lyrics.values():
            for line in section_lines:
                words = line.strip().split()
                total_words += len(words)
                unique_words.update(words)
                
                # 统计情感词汇
                for word in words:
                    if word in theme.keywords or any(
                        emotion in word for emotion in theme.emotional_range
                    ):
                        emotion_words += 1
        
        # 计算指标
        uniqueness_ratio = len(unique_words) / total_words if total_words > 0 else 0
        emotion_density = emotion_words / total_words if total_words > 0 else 0
        
        return {
            "total_words": total_words,
            "unique_words": len(unique_words),
            "uniqueness_ratio": f"{uniqueness_ratio:.1%}",
            "emotion_density": f"{emotion_density:.1%}",
            "section_count": len(lyrics),
            "average_lines_per_section": sum(len(l) for l in lyrics.values()) / len(lyrics)
        }
    
    def generate_song_idea(self, genre: str = "流行", 
                          mood: str = "快乐") -> Dict:
        """生成完整的歌曲创意"""
        
        # 随机选择主题
        theme_name = random.choice(list(self.themes.keys()))
        theme = self.themes[theme_name]
        
        # 选择结构
        if genre == "流行":
            structure = SongStructure.POP_STANDARD
            rhyme = RhymeScheme.AABB
        elif genre == "民谣":
            structure = SongStructure.BALLAD
            rhyme = RhymeScheme.ABAB
        elif genre == "摇滚":
            structure = SongStructure.ROCK
            rhyme = RhymeScheme.FREE
        elif genre == "嘻哈":
            structure = SongStructure.HIPHOP
            rhyme = RhymeScheme.MULTI
        else:
            structure = theme.typical_structure
            rhyme = RhymeScheme.AABB
        
        # 生成歌词
        lyrics_data = self.generate_structured_lyrics(
            theme_name=theme_name,
            structure=structure,
            rhyme_scheme=rhyme,
            line_length=random.randint(6, 10)
        )
        
        # 生成标题
        title = self._generate_title(theme, mood)
        
        # 生成提示词
        prompt = self._generate_suno_prompt(title, lyrics_data, genre, mood)
        
        return {
            "title": title,
            "theme": theme_name,
            "genre": genre,
            "mood": mood,
            "structure": structure.value,
            "rhyme_scheme": rhyme.value,
            "lyrics": lyrics_data["full_lyrics"],
            "lyrics_analysis": lyrics_data["analysis"],
            "suno_prompt": prompt,
            "recommended_instruments": self._get_recommended_instruments(genre),
            "recommended_tempo": self._get_recommended_tempo(mood, genre)
        }
    
    def _generate_title(self, theme: SongTheme, mood: str) -> str:
        """生成歌曲标题"""
        
        # 组合词汇生成标题
        vocab_sets = [
            self.vocabulary["自然"],
            self.vocabulary["情感"],
            self.vocabulary["时间"]
        ]
        
        word1 = random.choice(random.choice(vocab_sets))
        word2 = random.choice(theme.keywords)
        
        # 标题模板
        templates = [
            f"{word1}的{word2}",
            f"{word2}{word1}",
            f"{word1}{word2}",
            f"{mood}{word1}",
            f"{word2}之{word1}"
        ]
        
        return random.choice(templates)
    
    def _generate_suno_prompt(self, title: str, lyrics_data: Dict, 
                             genre: str, mood: str) -> str:
        """生成Suno提示词"""
        
        prompt = f"创作一首歌曲,标题:{title}\n\n"
        prompt += f"风格:{genre},情绪:{mood}\n\n"
        prompt += "歌词:\n"
        prompt += lyrics_data["full_lyrics"] + "\n\n"
        prompt += "要求:\n"
        prompt += "1. 旋律优美,容易记忆\n"
        prompt += "2. 节奏与情绪相匹配\n"
        prompt += "3. 乐器编排丰富但不过度\n"
        prompt += "4. 人声清晰,情感表达充分\n"
        
        if genre == "流行":
            prompt += "5. 副歌部分要朗朗上口,适合传唱\n"
        elif genre == "民谣":
            prompt += "5. 突出吉他或钢琴伴奏,质朴自然\n"
        elif genre == "电子":
            prompt += "5. 使用合成器音色,节奏感强\n"
        
        return prompt
    
    def _get_recommended_instruments(self, genre: str) -> List[str]:
        """获取推荐乐器"""
        
        instrument_map = {
            "流行": ["钢琴", "吉他", "鼓组", "贝斯", "弦乐"],
            "摇滚": ["电吉他", "贝斯", "鼓组", "键盘"],
            "民谣": ["吉他", "钢琴", "口琴", "小提琴"],
            "电子": ["合成器", "鼓机", "贝斯", "电子音效"],
            "R&B": ["钢琴", "贝斯", "鼓", "弦乐", "和声"],
            "爵士": ["萨克斯", "钢琴", "贝斯", "鼓", "小号"],
            "国风": ["二胡", "古筝", "笛子", "琵琶", "钢琴"]
        }
        
        return instrument_map.get(genre, instrument_map["流行"])
    
    def _get_recommended_tempo(self, mood: str, genre: str) -> str:
        """获取推荐速度"""
        
        # BPM范围
        tempo_map = {
            "快乐": {"流行": "120-140 BPM", "摇滚": "140-160 BPM", "电子": "128-150 BPM"},
            "悲伤": {"流行": "60-80 BPM", "民谣": "70-90 BPM", "R&B": "70-85 BPM"},
            "浪漫": {"流行": "90-110 BPM", "爵士": "100-120 BPM", "R&B": "85-105 BPM"},
            "励志": {"流行": "120-140 BPM", "摇滚": "140-160 BPM", "电子": "128-150 BPM"},
            "放松": {"民谣": "70-90 BPM", "爵士": "80-100 BPM", "古典": "60-80 BPM"}
        }
        
        mood_tempos = tempo_map.get(mood, tempo_map["快乐"])
        return mood_tempos.get(genre, "100-120 BPM")

# 使用示例
if __name__ == "__main__":
    engineer = LyricEngineer()
    
    # 示例1: 生成结构化歌词
    print("示例1: 生成结构化歌词")
    lyrics_data = engineer.generate_structured_lyrics(
        theme_name="爱情",
        structure=SongStructure.POP_STANDARD,
        rhyme_scheme=RhymeScheme.AABB,
        line_length=8
    )
    
    print(f"\n歌曲主题: {lyrics_data['theme']}")
    print(f"歌曲结构: {lyrics_data['structure']}")
    print(f"押韵方案: {lyrics_data['rhyme_scheme']}")
    print(f"总行数: {lyrics_data['total_lines']}")
    
    print("\n完整歌词:")
    print(lyrics_data['full_lyrics'])
    
    print("\n歌词分析:")
    for key, value in lyrics_data['analysis'].items():
        print(f"{key}: {value}")
    
    # 示例2: 生成完整歌曲创意
    print("\n" + "="*60)
    print("示例2: 生成完整歌曲创意")
    
    song_idea = engineer.generate_song_idea(
        genre="流行",
        mood="浪漫"
    )
    
    print(f"\n🎵 歌曲标题: {song_idea['title']}")
    print(f"🎭 主题: {song_idea['theme']}")
    print(f"🎸 风格: {song_idea['genre']}")
    print(f"😊 情绪: {song_idea['mood']}")
    print(f"📐 结构: {song_idea['structure']}")
    
    print(f"\n🎼 推荐乐器: {', '.join(song_idea['recommended_instruments'])}")
    print(f"🎚️  推荐速度: {song_idea['recommended_tempo']}")
    
    print(f"\n📝 Suno提示词(前200字符):")
    print(song_idea['suno_prompt'][:200] + "...")

3.2 高级提示词工程

# advanced_prompt_engineering.py
"""
Suno高级提示词工程系统
生成专业级音乐创作提示词
"""

import re
from typing import Dict, List, Tuple, Optional
from dataclasses import dataclass
from enum import Enum
import json

class MusicGenre(Enum):
    """音乐流派详细分类"""
    POP = "流行音乐"
    ROCK = "摇滚乐"
    HIPHOP = "嘻哈音乐"
    EDM = "电子舞曲"
    JAZZ = "爵士乐"
    CLASSICAL = "古典音乐"
    COUNTRY = "乡村音乐"
    RNB = "节奏布鲁斯"
    REGGAE = "雷鬼音乐"
    METAL = "金属音乐"
    INDIE = "独立音乐"
    K_POP = "韩流音乐"
    C_POP = "华语流行"
    J_POP = "日本流行"
    LOFI = "低保真"
    AMBIENT = "氛围音乐"
    SYNTHWAVE = "合成器浪潮"
    FUNK = "放克音乐"
    SOUL = "灵魂乐"
    BLUES = "布鲁斯"

class InstrumentFamily(Enum):
    """乐器家族"""
    STRINGS = "弦乐器"
    WOODWINDS = "木管乐器"
    BRASS = "铜管乐器"
    PERCUSSION = "打击乐器"
    KEYBOARD = "键盘乐器"
    ELECTRONIC = "电子乐器"
    VOCAL = "人声"
    ETHNIC = "民族乐器"

class ProductionStyle(Enum):
    """制作风格"""
    LIVE = "现场录制"
    STUDIO = "录音室"
    DIY = "独立制作"
    ORCHESTRAL = "管弦乐"
    MINIMAL = "极简主义"
    LAYERED = "分层丰富"
    SPACIOUS = "空间感强"
    INTIMATE = "亲密感"
    EPIC = "史诗感"

@dataclass
class AdvancedPrompt:
    """高级提示词"""
    core_concept: str
    genre: MusicGenre
    mood: str
    tempo: str
    instruments: List[str]
    production_style: ProductionStyle
    lyrical_themes: List[str]
    structure_hints: str
    sound_qualities: List[str]
    reference_artists: List[str]
    
    def to_suno_prompt(self) -> str:
        """转换为Suno提示词"""
        
        prompt = f"创作一首{self.genre.value},主题是:{self.core_concept}\n\n"
        
        prompt += "【音乐风格与情绪】\n"
        prompt += f"- 风格:{self.genre.value}\n"
        prompt += f"- 情绪:{self.mood}\n"
        prompt += f"- 速度:{self.tempo}\n"
        prompt += f"- 制作风格:{self.production_style.value}\n\n"
        
        prompt += "【乐器与音色】\n"
        prompt += f"- 主要乐器:{', '.join(self.instruments)}\n"
        prompt += f"- 声音特质:{', '.join(self.sound_qualities)}\n\n"
        
        prompt += "【歌词主题】\n"
        prompt += f"- 主题元素:{', '.join(self.lyrical_themes)}\n\n"
        
        prompt += "【结构提示】\n"
        prompt += f"{self.structure_hints}\n\n"
        
        prompt += "【参考艺术家】\n"
        prompt += f"参考以下艺术家的风格元素:{', '.join(self.reference_artists)}\n\n"
        
        prompt += "【具体要求】\n"
        prompt += "1. 旋律要令人难忘且情感丰富\n"
        prompt += "2. 编曲层次分明,有动态变化\n"
        prompt += "3. 人声表现自然,情感真挚\n"
        prompt += "4. 整体制作精良,适合反复聆听\n"
        
        return prompt

class AdvancedPromptEngineer:
    """高级提示词工程师"""
    
    def __init__(self):
        # 初始化知识库
        self.genre_knowledge = self._init_genre_knowledge()
        self.mood_palette = self._init_mood_palette()
        self.instrument_library = self._init_instrument_library()
        
    def _init_genre_knowledge(self) -> Dict[MusicGenre, Dict]:
        """初始化流派知识库"""
        return {
            MusicGenre.POP: {
                "tempo_range": "100-130 BPM",
                "common_instruments": ["钢琴", "吉他", "鼓", "贝斯", "合成器"],
                "structure": "主歌-预副歌-副歌-主歌-副歌-桥段-副歌",
                "characteristics": ["朗朗上口的旋律", "明确的节拍", "重复的副歌"],
                "reference_artists": ["Taylor Swift", "Ed Sheeran", "Ariana Grande"]
            },
            MusicGenre.LOFI: {
                "tempo_range": "70-90 BPM",
                "common_instruments": ["钢琴", "黑胶采样", "低保真鼓", "环境音效"],
                "structure": "循环结构,渐进变化",
                "characteristics": ["温暖的质感", "轻微的失真", "放松的节奏"],
                "reference_artists": ["Jinsang", "Tomppabeats", " idealism"]
            },
            MusicGenre.SYNTHWAVE: {
                "tempo_range": "100-120 BPM",
                "common_instruments": ["模拟合成器", "鼓机", "贝斯", "人声和声"],
                "structure": "主旋律重复,氛围渐进",
                "characteristics": ["复古未来感", "丰富的和声", "强烈的节奏"],
                "reference_artists": ["The Midnight", "FM-84", "Timecop1983"]
            },
            MusicGenre.C_POP: {
                "tempo_range": "80-120 BPM",
                "common_instruments": ["钢琴", "弦乐", "传统乐器", "电子元素"],
                "structure": "主歌-副歌-主歌-副歌-桥段-副歌",
                "characteristics": ["旋律优美", "情感丰富", "歌词诗意"],
                "reference_artists": ["周杰伦", "林俊杰", "邓紫棋"]
            }
        }
    
    def _init_mood_palette(self) -> Dict[str, Dict]:
        """初始化情绪调色板"""
        return {
            "怀旧": {
                "description": "对过去的温柔回忆",
                "musical_traits": ["缓慢的节奏", "温暖的音色", "简单的旋律"],
                "lyrical_themes": ["童年记忆", "旧时光", "逝去的爱情"],
                "sound_qualities": ["温暖", "朦胧", "柔和"]
            },
            "未来感": {
                "description": "对未来的科技幻想",
                "musical_traits": ["电子音色", "重复的节奏", "空间感"],
                "lyrical_themes": ["科技进步", "宇宙探索", "数字生活"],
                "sound_qualities": ["冰冷", "清晰", "广阔"]
            },
            "都市夜晚": {
                "description": "城市夜晚的孤独与美丽",
                "musical_traits": ["慢节奏", "氛围感", "轻微爵士影响"],
                "lyrical_themes": ["霓虹灯光", "雨夜漫步", "城市孤独"],
                "sound_qualities": ["湿润", "迷离", "深夜感"]
            },
            "自然治愈": {
                "description": "大自然带来的平静与治愈",
                "musical_traits": ["自然采样", "简单旋律", "环境音效"],
                "lyrical_themes": ["森林漫步", "海边日落", "四季变化"],
                "sound_qualities": ["清新", "自然", "平静"]
            }
        }
    
    def _init_instrument_library(self) -> Dict[InstrumentFamily, List[str]]:
        """初始化乐器库"""
        return {
            InstrumentFamily.STRINGS: [
                "小提琴", "大提琴", "中提琴", "低音提琴",
                "吉他", "电吉他", "贝斯", "尤克里里",
                "竖琴", "古筝", "二胡", "琵琶"
            ],
            InstrumentFamily.KEYBOARD: [
                "钢琴", "电钢琴", "合成器", "风琴",
                "键盘", "电子琴", "钟琴", "钢片琴"
            ],
            InstrumentFamily.PERCUSSION: [
                "鼓组", "架子鼓", "手鼓", "康加鼓",
                "铃鼓", "三角铁", "木鱼", "沙锤",
                "电子鼓", "打击板"
            ],
            InstrumentFamily.ELECTRONIC: [
                "合成器贝斯", "电子音效", "氛围采样",
                "节拍器", "效果器", "声码器"
            ],
            InstrumentFamily.VOCAL: [
                "主唱", "和声", "合唱", "人声采样",
                "说唱", "吟唱", "口语"
            ]
        }
    
    def create_custom_prompt(self, concept: str, genre: MusicGenre = MusicGenre.POP,
                            mood: str = "怀旧", complexity: str = "中等") -> AdvancedPrompt:
        """创建自定义提示词"""
        
        print(f"🎨 为 '{concept}' 创建高级提示词")
        print(f"🎸 流派: {genre.value}")
        print(f"😊 情绪: {mood}")
        print(f"⚙️  复杂度: {complexity}")
        
        # 获取流派知识
        genre_info = self.genre_knowledge.get(genre, self.genre_knowledge[MusicGenre.POP])
        
        # 获取情绪信息
        mood_info = self.mood_palette.get(mood, self.mood_palette["怀旧"])
        
        # 选择乐器
        instruments = self._select_instruments(genre, mood, complexity)
        
        # 生成结构提示
        structure_hints = self._generate_structure_hints(genre, complexity)
        
        # 选择制作风格
        production_style = self._select_production_style(genre, mood)
        
        # 生成提示词
        prompt = AdvancedPrompt(
            core_concept=concept,
            genre=genre,
            mood=mood,
            tempo=genre_info["tempo_range"],
            instruments=instruments,
            production_style=production_style,
            lyrical_themes=mood_info["lyrical_themes"],
            structure_hints=structure_hints,
            sound_qualities=mood_info["sound_qualities"],
            reference_artists=genre_info["reference_artists"]
        )
        
        return prompt
    
    def _select_instruments(self, genre: MusicGenre, mood: str, 
                           complexity: str) -> List[str]:
        """选择乐器组合"""
        
        base_instruments = []
        
        # 根据流派选择基础乐器
        genre_info = self.genre_knowledge.get(genre)
        if genre_info and "common_instruments" in genre_info:
            base_instruments = genre_info["common_instruments"][:3]
        
        # 根据情绪添加特色乐器
        if mood in ["怀旧", "自然治愈"]:
            base_instruments.extend(["原声吉他", "钢琴", "环境采样"])
        
        if mood in ["未来感", "都市夜晚"]:
            base_instruments.extend(["合成器", "鼓机", "电子音效"])
        
        # 根据复杂度调整
        if complexity == "简单":
            return base_instruments[:3]
        elif complexity == "中等":
            return base_instruments[:5]
        else:  # 复杂
            # 添加更多乐器
            extra_instruments = []
            
            if genre == MusicGenre.C_POP:
                extra_instruments.extend(["二胡", "古筝", "笛子"])
            elif genre == MusicGenre.SYNTHWAVE:
                extra_instruments.extend(["模拟合成器", "人声和声", "贝斯"])
            
            return base_instruments + extra_instruments[:2]
    
    def _generate_structure_hints(self, genre: MusicGenre, complexity: str) -> str:
        """生成结构提示"""
        
        genre_info = self.genre_knowledge.get(genre)
        
        if not genre_info:
            return "标准流行歌曲结构:主歌-副歌-主歌-副歌-桥段-副歌"
        
        base_structure = genre_info.get("structure", "标准结构")
        
        if complexity == "简单":
            return f"简单结构:{base_structure},保持简洁"
        elif complexity == "中等":
            return f"中等复杂度结构:{base_structure},加入前奏和间奏"
        else:
            return f"复杂结构:{base_structure},加入多个桥段变化、器乐独奏和动态起伏"
    
    def _select_production_style(self, genre: MusicGenre, mood: str) -> ProductionStyle:
        """选择制作风格"""
        
        if genre in [MusicGenre.CLASSICAL, MusicGenre.JAZZ]:
            return ProductionStyle.LIVE
        
        if genre in [MusicGenre.LOFI, MusicGenre.INDIE]:
            return ProductionStyle.DIY
        
        if mood in ["史诗感", "未来感"]:
            return ProductionStyle.EPIC
        
        if mood in ["亲密感", "怀旧"]:
            return ProductionStyle.INTIMATE
        
        return ProductionStyle.STUDIO
    
    def analyze_and_improve_prompt(self, user_prompt: str) -> Dict:
        """分析并改进用户提示词"""
        
        analysis = {
            "original": user_prompt,
            "length": len(user_prompt),
            "word_count": len(user_prompt.split()),
            "issues": [],
            "suggestions": [],
            "improved_prompt": ""
        }
        
        # 检查常见问题
        if len(user_prompt) < 20:
            analysis["issues"].append("提示词过短,信息不足")
            analysis["suggestions"].append("添加更多关于风格、情绪、乐器的描述")
        
        if len(user_prompt) > 500:
            analysis["issues"].append("提示词过长,可能混淆AI")
            analysis["suggestions"].append("精简到300字以内,突出重点")
        
        # 检查关键元素
        has_genre = any(genre.value in user_prompt for genre in MusicGenre)
        has_mood = any(mood in user_prompt for mood in self.mood_palette.keys())
        has_instruments = any(
            instrument in user_prompt 
            for instruments in self.instrument_library.values() 
            for instrument in instruments
        )
        
        if not has_genre:
            analysis["issues"].append("未指定音乐流派")
            analysis["suggestions"].append("明确指定流派,如'流行音乐'、'电子音乐'")
        
        if not has_mood:
            analysis["issues"].append("未指定情绪氛围")
            analysis["suggestions"].append("添加情绪描述,如'怀旧的'、'欢快的'")
        
        if not has_instruments:
            analysis["issues"].append("未指定乐器")
            analysis["suggestions"].append("指定1-3种主要乐器")
        
        # 生成改进版提示词
        improved = self._improve_prompt(user_prompt, analysis["issues"])
        analysis["improved_prompt"] = improved
        
        return analysis
    
    def _improve_prompt(self, original: str, issues: List[str]) -> str:
        """改进提示词"""
        
        improved = original
        
        # 如果过短,添加结构化内容
        if "提示词过短" in issues:
            improved += "\n\n【补充说明】\n"
            improved += "风格:流行音乐\n"
            improved += "情绪:温暖怀旧\n"
            improved += "乐器:钢琴、吉他、弦乐\n"
            improved += "结构:主歌-副歌-主歌-副歌-桥段-副歌\n"
        
        # 如果缺少流派,添加默认
        if "未指定音乐流派" in issues and "流行音乐" not in improved:
            improved = "创作一首流行音乐," + improved
        
        # 如果缺少情绪,添加默认
        if "未指定情绪氛围" in issues and "情绪" not in improved:
            improved += " 请以温暖怀旧的情绪创作。"
        
        # 如果缺少乐器,添加默认
        if "未指定乐器" in issues and "乐器" not in improved:
            improved += " 主要使用钢琴和吉他。"
        
        # 添加结构提示
        if "结构" not in improved:
            improved += " 歌曲结构采用标准的流行歌曲结构。"
        
        return improved
    
    def generate_prompt_variations(self, base_prompt: str, 
                                  num_variations: int = 3) -> List[str]:
        """生成提示词变体"""
        
        variations = []
        
        # 定义变体策略
        variation_strategies = [
            self._vary_genre,
            self._vary_mood,
            self._vary_instruments,
            self._vary_production
        ]
        
        for i in range(num_variations):
            strategy = variation_strategies[i % len(variation_strategies)]
            variation = strategy(base_prompt)
            variations.append(variation)
        
        return variations
    
    def _vary_genre(self, prompt: str) -> str:
        """变化流派"""
        
        genres_to_try = [MusicGenre.LOFI, MusicGenre.SYNTHWAVE, MusicGenre.C_POP]
        
        for genre in genres_to_try:
            if genre.value not in prompt:
                # 替换或添加流派
                for existing_genre in MusicGenre:
                    if existing_genre.value in prompt:
                        return prompt.replace(existing_genre.value, genre.value)
                
                # 如果没有找到流派,在开头添加
                return f"创作一首{genre.value}," + prompt
        
        return prompt
    
    def _vary_mood(self, prompt: str) -> str:
        """变化情绪"""
        
        moods_to_try = ["未来感", "都市夜晚", "自然治愈"]
        
        for mood in moods_to_try:
            if mood not in prompt:
                # 替换或添加情绪
                for existing_mood in self.mood_palette.keys():
                    if existing_mood in prompt:
                        return prompt.replace(existing_mood, mood)
                
                # 如果没有找到情绪,在末尾添加
                return prompt + f" 请以{mood}的情绪创作。"
        
        return prompt
    
    def _vary_instruments(self, prompt: str) -> str:
        """变化乐器"""
        
        instrument_groups = [
            ["合成器", "鼓机", "电子贝斯"],
            ["二胡", "古筝", "笛子"],
            ["原声吉他", "口琴", "手鼓"]
        ]
        
        for group in instrument_groups:
            # 检查是否有这些乐器
            has_any = any(instrument in prompt for instrument in group)
            if not has_any:
                # 添加乐器说明
                return prompt + f" 主要使用{group[0]}{group[1]}。"
        
        return prompt
    
    def _vary_production(self, prompt: str) -> str:
        """变化制作风格"""
        
        production_styles = [
            "低保真DIY制作风格",
            "录音室精良制作",
            "现场演出感觉"
        ]
        
        for style in production_styles:
            if style not in prompt:
                return prompt + f" 采用{style}。"
        
        return prompt

# 使用示例
if __name__ == "__main__":
    engineer = AdvancedPromptEngineer()
    
    # 示例1: 创建高级提示词
    print("示例1: 创建高级提示词")
    
    custom_prompt = engineer.create_custom_prompt(
        concept="雨夜中的城市漫步",
        genre=MusicGenre.LOFI,
        mood="都市夜晚",
        complexity="中等"
    )
    
    print(f"\n🎨 核心概念: {custom_prompt.core_concept}")
    print(f"🎸 流派: {custom_prompt.genre.value}")
    print(f"😊 情绪: {custom_prompt.mood}")
    print(f"🎚️  速度: {custom_prompt.tempo}")
    print(f"🎹 乐器: {', '.join(custom_prompt