benjamin5607 commited on
Commit
3f6565c
Β·
verified Β·
1 Parent(s): 8ee2277

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +45 -71
app.py CHANGED
@@ -8,119 +8,93 @@ import scipy.io.wavfile
8
  import numpy as np
9
  from transformers import pipeline
10
 
11
- # 1. API ν‚€ (ν™˜κ²½λ³€μˆ˜ μ„€μ • ν•„μˆ˜!)
12
  GENAI_KEY = os.getenv("GEMINI_KEY")
13
 
14
- # 2. [μž‘κ³‘κ°€] MusicGen λͺ¨λΈ λ‘œλ“œ
15
- print("⏳ μž‘κ³‘κ°€(MusicGen) μ„­μ™Έ 쀑... (μ΅œλŒ€ 1~2λΆ„ μ†Œμš”)")
16
  try:
17
- # facebook/musicgen-small : 가볍고 λΉ λ₯Έ λͺ¨λΈ
18
  music_synthesiser = pipeline("text-to-audio", "facebook/musicgen-small")
19
- print("βœ… μž‘κ³‘κ°€ μ„­μ™Έ μ™„λ£Œ! Start Jamming!")
20
  except Exception as e:
21
- print(f"⚠️ μž‘κ³‘ λͺ¨λΈ λ‘œλ“œ μ‹€νŒ¨: {e}")
22
  music_synthesiser = None
23
 
24
- # 3. Gemini λͺ¨λΈ μ°ΎκΈ° 헬퍼
25
  def find_working_model():
26
  url = f"https://generativelanguage.googleapis.com/v1beta/models?key={GENAI_KEY}"
27
  try:
28
  response = requests.get(url)
29
- if response.status_code != 200: return "gemini-pro"
30
  data = response.json()
31
  candidates = [m['name'].replace("models/", "") for m in data.get('models', []) if 'generateContent' in m.get('supportedGenerationMethods', [])]
32
- preferred = ["gemini-1.5-flash", "gemini-1.5-flash-latest", "gemini-pro"]
33
  for p in preferred:
34
  if p in candidates: return p
35
  return candidates[0] if candidates else "gemini-pro"
36
- except:
37
- return "gemini-pro"
38
 
39
  ACTIVE_MODEL = find_working_model()
40
 
41
- # 4. 멀버 페λ₯΄μ†Œλ‚˜ μ •μ˜
42
  MEMBERS = {
43
- "μ„œμœ€ (Korea)": { "voice": "ko-KR-SunHiNeural", "prompt": "당신은 λ‘λ°΄λ“œ 보컬 'μ„œμœ€'μž…λ‹ˆλ‹€. ν•œκ΅­μ–΄(Korean)둜 λŒ€λ‹΅ν•˜μ„Έμš”. 성격: μ‹œλ‹ˆμ»¬ν•˜μ§€λ§Œ μŒμ•…μ—” 진심. λ‹΅λ³€ 끝에 μž‘κ³‘ 아이디어λ₯Ό ν¬ν•¨ν•˜μ„Έμš”." },
44
- "Chloe (USA)": { "voice": "en-US-AriaNeural", "prompt": "You are 'Chloe', the lead guitarist. Speak in English. Personality: Cool rockstar. Suggest guitar riffs." },
45
- "Beatrice (Brazil)": { "voice": "pt-BR-FranciscaNeural", "prompt": "You are 'Beatrice', the drummer. Speak in English/Portuguese. Focus on rhythm and groove." },
46
- "Naomi (Japan)": { "voice": "ja-JP-NanamiNeural", "prompt": "You are 'Naomi'. Speak in Japanese. Focus on melody and chords." },
47
- "Elena (Spain)": { "voice": "es-ES-ElviraNeural", "prompt": "You are 'Elena'. Speak in Spanish/English. Focus on bass lines." },
48
- "Amira (Egypt)": { "voice": "ar-EG-SalmaNeural", "prompt": "You are 'Amira'. Speak in Arabic/English. Focus on atmosphere." },
49
- "Liwei (China)": { "voice": "zh-CN-XiaoxiaoNeural", "prompt": "You are 'Liwei'. Speak in Chinese/English. Focus on FX and sound design." },
50
- "Sophie (France)": { "voice": "fr-FR-DeniseNeural", "prompt": "You are 'Sophie'. Speak in French/English. Focus on emotional melody." }
51
  }
52
 
53
- async def band_consulting(user_input, member_name):
54
  try:
55
- if member_name not in MEMBERS:
56
- return "Error: Unknown Member", None, None
57
-
58
- member = MEMBERS[member_name]
59
 
60
- # β˜… μ‹œμŠ€ν…œ ν”„λ‘¬ν”„νŠΈ: μž‘κ³‘ λͺ…λ Ή [MUSIC:...] 을 μœ λ„
61
  system_instruction = f"""
62
  {member['prompt']}
 
63
 
64
- [INSTRUCTION]
65
- 1. Give advice based on the user's input.
66
- 2. IF appropriate (user asks for music, sample, or feeling), create a short music sample.
67
- 3. To create music, write a hidden command at the END of your response like this:
68
- [MUSIC: genre, tempo, instruments, mood]
69
-
70
- Example: "Let's go with a heavy beat! [MUSIC: heavy metal drum beat, 140bpm, aggressive]"
71
- If no music needed, do NOT write [MUSIC:...].
72
  """
73
 
74
- # Gemini 호좜
75
  url = f"https://generativelanguage.googleapis.com/v1beta/models/{ACTIVE_MODEL}:generateContent?key={GENAI_KEY}"
76
- payload = {"contents": [{"parts": [{"text": f"{system_instruction}\nUser: {user_input}\nResponse:"}]}]}
77
- res = requests.post(url, json=payload, headers={'Content-Type': 'application/json'})
78
-
79
- if res.status_code != 200:
80
- return f"API Error: {res.text}", None, None
81
-
82
  ai_text_raw = res.json()['candidates'][0]['content']['parts'][0]['text']
83
 
84
- # μŒμ•… λͺ…λ Ή μΆ”μΆœ
85
- music_prompt = None
86
- clean_text = ai_text_raw
87
- match = re.search(r'\[MUSIC:(.*?)\]', ai_text_raw, re.IGNORECASE)
88
 
89
- if match:
90
- music_prompt = match.group(1).strip()
91
- clean_text = ai_text_raw.replace(match.group(0), "").strip()
92
- print(f"🎡 μž‘κ³‘ μš”μ²­: {music_prompt}")
93
 
94
- # TTS (λͺ©μ†Œλ¦¬) 생성
95
- voice_path = f"/tmp/{member_name}_voice.mp3"
96
  await edge_tts.Communicate(clean_text, member['voice']).save(voice_path)
97
 
98
- # MusicGen (μŒμ•…) 생성
99
  music_path = None
100
- if music_prompt and music_synthesiser:
101
- try:
102
- # max_new_tokens=256 (μ•½ 5초) ~ 512 (μ•½ 10초)
103
- music = music_synthesiser(music_prompt, forward_params={"max_new_tokens": 512})
104
- music_path = f"/tmp/{member_name}_music.wav"
105
- scipy.io.wavfile.write(music_path, music["sampling_rate"], music["audio"][0].T)
106
- except Exception as e:
107
- print(f"❌ μž‘κ³‘ μ‹€νŒ¨: {e}")
108
 
109
- return clean_text, voice_path, music_path
110
 
111
  except Exception as e:
112
- return f"System Error: {e}", None, None
113
 
114
- # Gradio μ•± μ‹€ν–‰
115
  with gr.Blocks() as demo:
116
  with gr.Row():
117
- inp = gr.Textbox(label="Input")
118
- mem = gr.Textbox(label="Member")
119
- out_text = gr.Textbox(label="Advice")
120
- out_voice = gr.Audio(label="Voice")
121
- out_music = gr.Audio(label="Music Sample")
122
-
123
- btn = gr.Button("GO")
124
- btn.click(band_consulting, [inp, mem], [out_text, out_voice, out_music], api_name="predict")
125
 
126
  demo.launch()
 
8
  import numpy as np
9
  from transformers import pipeline
10
 
11
+ # API ν‚€ μ„€μ •
12
  GENAI_KEY = os.getenv("GEMINI_KEY")
13
 
14
+ # 1. [μž‘κ³‘κ°€] MusicGen λ‘œλ“œ (음질 보정 μ„€μ • μ€€λΉ„)
15
+ print("⏳ μž‘κ³‘κ°€ μ„­μ™Έ 쀑... (음질 보정 λͺ¨λ“œ)")
16
  try:
 
17
  music_synthesiser = pipeline("text-to-audio", "facebook/musicgen-small")
18
+ print("βœ… μž‘κ³‘κ°€ μ€€λΉ„ μ™„λ£Œ!")
19
  except Exception as e:
20
+ print(f"⚠️ λͺ¨λΈ λ‘œλ“œ μ‹€νŒ¨: {e}")
21
  music_synthesiser = None
22
 
 
23
  def find_working_model():
24
  url = f"https://generativelanguage.googleapis.com/v1beta/models?key={GENAI_KEY}"
25
  try:
26
  response = requests.get(url)
 
27
  data = response.json()
28
  candidates = [m['name'].replace("models/", "") for m in data.get('models', []) if 'generateContent' in m.get('supportedGenerationMethods', [])]
29
+ preferred = ["gemini-1.5-flash", "gemini-pro"]
30
  for p in preferred:
31
  if p in candidates: return p
32
  return candidates[0] if candidates else "gemini-pro"
33
+ except: return "gemini-pro"
 
34
 
35
  ACTIVE_MODEL = find_working_model()
36
 
37
+ # 멀버 페λ₯΄μ†Œλ‚˜ (악보 생성 λŠ₯λ ₯ μΆ”κ°€)
38
  MEMBERS = {
39
+ "μ„œμœ€ (Korea)": { "voice": "ko-KR-SunHiNeural", "prompt": "당신은 보컬 'μ„œμœ€'μž…λ‹ˆλ‹€. μ‹œλ‹ˆμ»¬ν•œ 말투. 상담 뢄야에 맞좰 μŒμ•…μ  μ‘°μ–Έκ³Ό μ½”λ“œ 진행을 μ•Œλ €μ£Όμ„Έμš”." },
40
+ "Chloe (USA)": { "voice": "en-US-AriaNeural", "prompt": "You are 'Chloe', the guitarist. Speak in English. Focus on guitar tabs and tones." },
41
+ "Beatrice (Brazil)": { "voice": "pt-BR-FranciscaNeural", "prompt": "You are 'Beatrice', the drummer. Focus on rhythm patterns and groovy beats." }
 
 
 
 
 
42
  }
43
 
44
+ async def band_consulting(user_input, member_name, consult_category):
45
  try:
46
+ member = MEMBERS.get(member_name, MEMBERS["μ„œyun (Korea)"])
 
 
 
47
 
48
+ # μ‹œμŠ€ν…œ ν”„λ‘¬ν”„νŠΈ: 악보와 μŒμ•… 생성을 ꡬ체화
49
  system_instruction = f"""
50
  {member['prompt']}
51
+ [상담 λΆ„μ•Ό: {consult_category}]
52
 
53
+ 당신은 μ „λ¬Έκ°€λ‘œμ„œ 쑰언을 ν•˜κ³ , λ§ˆμ§€λ§‰μ— 두 κ°€μ§€λ₯Ό λ°˜λ“œμ‹œ ν¬ν•¨ν•˜μ„Έμš”:
54
+ 1. [TAB]: μŒμ•…μ˜ κ°„λ‹¨ν•œ μ•…λ³΄λ‚˜ μ½”λ“œ 진행을 ν…μŠ€νŠΈ ν˜•μ‹μœΌλ‘œ κ·Έλ¦¬μ„Έμš”.
55
+ 예: | Am - F - C - G |
56
+ 2. [MUSIC]: 뢄야에 νŠΉν™”λœ 고음질 μŒμ•… ν”„λ‘¬ν”„νŠΈλ₯Ό μ μœΌμ„Έμš”.
57
+ (High-quality, studio recording, master audio ν•„μˆ˜ 포함)
 
 
 
58
  """
59
 
 
60
  url = f"https://generativelanguage.googleapis.com/v1beta/models/{ACTIVE_MODEL}:generateContent?key={GENAI_KEY}"
61
+ payload = {"contents": [{"parts": [{"text": f"{system_instruction}\n질문: {user_input}"}]}]}
62
+ res = requests.post(url, json=payload)
 
 
 
 
63
  ai_text_raw = res.json()['candidates'][0]['content']['parts'][0]['text']
64
 
65
+ # 악보([TAB])와 μŒμ•…([MUSIC]) μΆ”μΆœ
66
+ tab_match = re.search(r'\[TAB\](.*?)\[', ai_text_raw + '[', re.DOTALL)
67
+ music_match = re.search(r'\[MUSIC:(.*?)\]', ai_text_raw, re.IGNORECASE)
 
68
 
69
+ tab_display = tab_match.group(1).strip() if tab_match else "No Score Available"
70
+ clean_text = re.sub(r'\[TAB\].*?(\[|$)', '', ai_text_raw, flags=re.DOTALL)
71
+ clean_text = re.sub(r'\[MUSIC:.*?\]', '', clean_text).strip()
 
72
 
73
+ # 1. λͺ©μ†Œλ¦¬ 생성
74
+ voice_path = f"/tmp/v_{member_name}.mp3"
75
  await edge_tts.Communicate(clean_text, member['voice']).save(voice_path)
76
 
77
+ # 2. μŒμ•… 생성 (음질 보정 트릭 적용)
78
  music_path = None
79
+ if music_match and music_synthesiser:
80
+ p = music_match.group(1).strip() + ", high quality, studio recording, clear sound"
81
+ # 음질 보정: guidance_scale을 λ†’μ—¬ ν”„λ‘¬ν”„νŠΈ 좩싀도 ν–₯상
82
+ music = music_synthesiser(p, forward_params={"max_new_tokens": 448, "guidance_scale": 4.5, "do_sample": True})
83
+ music_path = f"/tmp/m_{member_name}.wav"
84
+ scipy.io.wavfile.write(music_path, music["sampling_rate"], music["audio"][0].T)
 
 
85
 
86
+ return clean_text, voice_path, music_path, tab_display
87
 
88
  except Exception as e:
89
+ return f"Error: {e}", None, None, ""
90
 
91
+ # Gradio μΈν„°νŽ˜μ΄μŠ€
92
  with gr.Blocks() as demo:
93
  with gr.Row():
94
+ inp = gr.Textbox()
95
+ mem = gr.Textbox()
96
+ cat = gr.Textbox() # λΆ„μ•Ό
97
+ btn = gr.Button("Predict")
98
+ btn.click(band_consulting, [inp, mem, cat], [gr.Textbox(), gr.Audio(), gr.Audio(), gr.Textbox()], api_name="predict")
 
 
 
99
 
100
  demo.launch()