benjamin5607 commited on
Commit
1359090
Β·
verified Β·
1 Parent(s): fb6ce6a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +90 -36
app.py CHANGED
@@ -8,91 +8,145 @@ import scipy.io.wavfile
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
- # app.py의 band_consulting ν•¨μˆ˜ λΆ€λΆ„λ§Œ 이 λ‚΄μš©μœΌλ‘œ κ΅μ²΄ν•˜μ„Έμš”
 
44
  async def band_consulting(user_input, member_name, consult_category):
45
  try:
46
- # 멀버 이름 μ˜€νƒ€ μˆ˜μ •
47
  member = MEMBERS.get(member_name, MEMBERS["μ„œμœ€ (Korea)"])
48
 
49
  system_instruction = f"""
50
  {member['prompt']}
51
  [상담 λΆ„μ•Ό: {consult_category}]
52
- 당신은 μ „λ¬Έκ°€λ‘œμ„œ 쑰언을 ν•˜κ³ , λ§ˆμ§€λ§‰μ— 두 κ°€μ§€λ₯Ό λ°˜λ“œμ‹œ ν¬ν•¨ν•˜μ„Έμš”:
53
- 1. [TAB]: μŒμ•…μ˜ κ°„λ‹¨ν•œ μ•…λ³΄λ‚˜ μ½”λ“œ 진행을 ν…μŠ€νŠΈ ν˜•μ‹μœΌλ‘œ κ·Έλ¦¬μ„Έμš”.
54
- 2. [MUSIC]: 뢄야에 νŠΉν™”λœ 고음질 μŒμ•… ν”„λ‘¬ν”„νŠΈλ₯Ό μ μœΌμ„Έμš”.
 
 
55
  """
56
 
 
57
  url = f"https://generativelanguage.googleapis.com/v1beta/models/{ACTIVE_MODEL}:generateContent?key={GENAI_KEY}"
58
  payload = {"contents": [{"parts": [{"text": f"{system_instruction}\n질문: {user_input}"}]}]}
59
- res = requests.post(url, json=payload)
 
 
 
 
60
  ai_text_raw = res.json()['candidates'][0]['content']['parts'][0]['text']
61
 
62
- tab_match = re.search(r'\[TAB\](.*?)\[', ai_text_raw + '[', re.DOTALL)
 
63
  music_match = re.search(r'\[MUSIC:(.*?)\]', ai_text_raw, re.IGNORECASE)
64
 
65
- tab_display = tab_match.group(1).strip() if tab_match else "No Score"
66
 
67
- # 특수문자 읽기 λ°©μ§€ ν•„ν„° (TTS용 ν…μŠ€νŠΈμ—μ„œ 특수문자 제거)
68
- raw_clean_text = re.sub(r'\[TAB\].*?(\[|$)', '', ai_text_raw, flags=re.DOTALL)
69
- raw_clean_text = re.sub(r'\[MUSIC:.*?\]', '', raw_clean_text).strip()
70
- tts_text = re.sub(r'[\*\#\-\_\~]', '', raw_clean_text) # μ„œμœ€μ΄κ°€ 읽을 λ•Œ λ³„ν‘œ 등을 λ¬΄μ‹œν•¨
71
 
72
- # 1. λͺ©μ†Œλ¦¬ 생성 (ν•„ν„°λ§λœ tts_text μ‚¬μš©)
73
- voice_path = f"/tmp/v_{member_name}.mp3"
74
  await edge_tts.Communicate(tts_text, member['voice']).save(voice_path)
75
 
76
- # 2. μŒμ•… 생성
77
  music_path = None
78
  if music_match and music_synthesiser:
79
- p = music_match.group(1).strip() + ", high quality, studio recording"
80
- music = music_synthesiser(p, forward_params={"max_new_tokens": 448, "guidance_scale": 4.5})
81
- music_path = f"/tmp/m_{member_name}.wav"
82
- scipy.io.wavfile.write(music_path, music["sampling_rate"], music["audio"][0].T)
 
83
 
84
- return raw_clean_text, voice_path, music_path, tab_display
85
 
86
  except Exception as e:
87
- return f"Error: {e}", None, None, ""
 
88
 
89
- # Gradio μΈν„°νŽ˜μ΄μŠ€
90
  with gr.Blocks() as demo:
91
  with gr.Row():
92
- inp = gr.Textbox()
93
- mem = gr.Textbox()
94
- cat = gr.Textbox() # λΆ„μ•Ό
 
 
 
 
 
 
95
  btn = gr.Button("Predict")
96
- btn.click(band_consulting, [inp, mem, cat], [gr.Textbox(), gr.Audio(), gr.Audio(), gr.Textbox()], api_name="predict")
 
 
 
 
 
97
 
98
  demo.launch()
 
8
  import numpy as np
9
  from transformers import pipeline
10
 
11
+ # 1. API ν‚€ μ„€μ • (Hugging Face Settings -> Variables에 등둝 ν•„μˆ˜)
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("βœ… μž‘κ³‘κ°€ μ€€λΉ„ μ™„λ£Œ! 잼 μ„Έμ…˜μ„ μ‹œμž‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€.")
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
  data = response.json()
30
  candidates = [m['name'].replace("models/", "") for m in data.get('models', []) if 'generateContent' in m.get('supportedGenerationMethods', [])]
31
+ preferred = ["gemini-1.5-flash", "gemini-1.5-flash-latest", "gemini-pro"]
32
  for p in preferred:
33
  if p in candidates: return p
34
  return candidates[0] if candidates else "gemini-pro"
35
+ except:
36
+ return "gemini-pro"
37
 
38
  ACTIVE_MODEL = find_working_model()
39
 
40
+ # 4. λ°΄λ“œ 멀버 데이터 (이름 μ˜€νƒ€ μ™„λ²½ μˆ˜μ •: "μ„œμœ€ (Korea)")
41
  MEMBERS = {
42
+ "μ„œμœ€ (Korea)": {
43
+ "voice": "ko-KR-SunHiNeural",
44
+ "prompt": "당신은 λ‘λ°΄λ“œ 보컬 'μ„œμœ€'μž…λ‹ˆλ‹€. ν•œκ΅­μ–΄λ‘œ λŒ€λ‹΅ν•˜μ„Έμš”. 성격: μ‹œλ‹ˆμ»¬, 츀데레, μŒμ•…μ— 진심. 전문적인 μŒμ•… 쑰언을 μ œκ³΅ν•˜μ„Έμš”."
45
+ },
46
+ "Chloe (USA)": {
47
+ "voice": "en-US-AriaNeural",
48
+ "prompt": "You are 'Chloe', the lead guitarist. Respond in English. Focus on guitar tone and riffs."
49
+ },
50
+ "Beatrice (Brazil)": {
51
+ "voice": "pt-BR-FranciscaNeural",
52
+ "prompt": "You are 'Beatrice', the drummer. Focus on rhythm patterns and energy."
53
+ },
54
+ "Naomi (Japan)": {
55
+ "voice": "ja-JP-NanamiNeural",
56
+ "prompt": "You are 'Naomi'. Respond in Japanese. Focus on harmony and chord progressions."
57
+ },
58
+ "Elena (Spain)": {
59
+ "voice": "es-ES-ElviraNeural",
60
+ "prompt": "You are 'Elena'. Focus on bass lines and groove."
61
+ },
62
+ "Amira (Egypt)": {
63
+ "voice": "ar-EG-SalmaNeural",
64
+ "prompt": "You are 'Amira'. Focus on keyboards and atmosphere."
65
+ },
66
+ "Liwei (China)": {
67
+ "voice": "zh-CN-XiaoxiaoNeural",
68
+ "prompt": "You are 'Liwei'. Focus on electronic sound and FX."
69
+ },
70
+ "Sophie (France)": {
71
+ "voice": "fr-FR-DeniseNeural",
72
+ "prompt": "You are 'Sophie'. Focus on emotional melodies and violin."
73
+ }
74
  }
75
+
76
+ # 5. 메인 둜직 ν•¨μˆ˜
77
  async def band_consulting(user_input, member_name, consult_category):
78
  try:
79
+ # 멀버 μ°ΎκΈ° (κΈ°λ³Έκ°’: μ„œμœ€)
80
  member = MEMBERS.get(member_name, MEMBERS["μ„œμœ€ (Korea)"])
81
 
82
  system_instruction = f"""
83
  {member['prompt']}
84
  [상담 λΆ„μ•Ό: {consult_category}]
85
+
86
+ 쑰언을 μ œκ³΅ν•œ λ’€ λ°˜λ“œμ‹œ λ§ˆμ§€λ§‰μ— λ‹€μŒ ν˜•μ‹μ„ ν¬ν•¨ν•˜μ„Έμš”:
87
+ 1. [TAB]: μŒμ•…μ˜ κ°„λ‹¨ν•œ μ½”λ“œ μ§„ν–‰μ΄λ‚˜ ν…μŠ€νŠΈ 악보λ₯Ό κ·Έλ¦¬μ„Έμš”.
88
+ 2. [MUSIC]: 뢄야와 μ–΄μšΈλ¦¬λŠ” 고음질 μŒμ•… ν”„λ‘¬ν”„νŠΈλ₯Ό μ˜μ–΄λ‘œ μž‘μ„±ν•˜μ„Έμš”.
89
+ (예: [MUSIC: melodic rock guitar, high quality, studio recording, 120bpm])
90
  """
91
 
92
+ # Gemini API 호좜
93
  url = f"https://generativelanguage.googleapis.com/v1beta/models/{ACTIVE_MODEL}:generateContent?key={GENAI_KEY}"
94
  payload = {"contents": [{"parts": [{"text": f"{system_instruction}\n질문: {user_input}"}]}]}
95
+ res = requests.post(url, json=payload, headers={'Content-Type': 'application/json'})
96
+
97
+ if res.status_code != 200:
98
+ return "Gemini API 연결에 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.", None, None, "No Tab"
99
+
100
  ai_text_raw = res.json()['candidates'][0]['content']['parts'][0]['text']
101
 
102
+ # 악보([TAB]) 및 μŒμ•… λͺ…λ Ή([MUSIC]) μΆ”μΆœ
103
+ tab_match = re.search(r'\[TAB\](.*?)(\[|$)', ai_text_raw, re.DOTALL)
104
  music_match = re.search(r'\[MUSIC:(.*?)\]', ai_text_raw, re.IGNORECASE)
105
 
106
+ tab_display = tab_match.group(1).strip() if tab_match else "No Score Available"
107
 
108
+ # ν…μŠ€νŠΈ μ •μ œ 및 μŒμ„± 필터링 (특수문자 μ œκ±°ν•˜μ—¬ μ„œμœ€μ΄κ°€ 읽지 μ•Šκ²Œ 함)
109
+ clean_text = re.sub(r'\[TAB\].*?(\[|$)', '', ai_text_raw, flags=re.DOTALL)
110
+ clean_text = re.sub(r'\[MUSIC:.*?\]', '', clean_text).strip()
111
+ tts_text = re.sub(r'[\*\#\-\_\~]', '', clean_text)
112
 
113
+ # 6. λͺ©μ†Œλ¦¬(TTS) 생성
114
+ voice_path = f"/tmp/v_{member_name.replace(' ', '_')}.mp3"
115
  await edge_tts.Communicate(tts_text, member['voice']).save(voice_path)
116
 
117
+ # 7. μŒμ•…(MusicGen) 생성 (음질 보정 트릭)
118
  music_path = None
119
  if music_match and music_synthesiser:
120
+ music_p = music_match.group(1).strip() + ", high quality, studio recording, clear mix"
121
+ # guidance_scale=4.5둜 λ†’μ—¬ 음질 및 ν”„λ‘¬ν”„νŠΈ 정확도 ν–₯상
122
+ music_output = music_synthesiser(music_p, forward_params={"max_new_tokens": 448, "guidance_scale": 4.5, "do_sample": True})
123
+ music_path = f"/tmp/m_{member_name.replace(' ', '_')}.wav"
124
+ scipy.io.wavfile.write(music_path, music_output["sampling_rate"], music_output["audio"][0].T)
125
 
126
+ return clean_text, voice_path, music_path, tab_display
127
 
128
  except Exception as e:
129
+ print(f"❌ Error in band_consulting: {e}")
130
+ return f"λ°΄λ“œ μ‹œμŠ€ν…œ 였λ₯˜: {str(e)}", None, None, "Error"
131
 
132
+ # 8. Gradio μΈν„°νŽ˜μ΄μŠ€ μ •μ˜ (API용)
133
  with gr.Blocks() as demo:
134
  with gr.Row():
135
+ inp_text = gr.Textbox()
136
+ inp_member = gr.Textbox()
137
+ inp_cat = gr.Textbox()
138
+
139
+ out_advice = gr.Textbox()
140
+ out_voice = gr.Audio()
141
+ out_music = gr.Audio()
142
+ out_tab = gr.Textbox()
143
+
144
  btn = gr.Button("Predict")
145
+ btn.click(
146
+ fn=band_consulting,
147
+ inputs=[inp_text, inp_member, inp_cat],
148
+ outputs=[out_advice, out_voice, out_music, out_tab],
149
+ api_name="predict"
150
+ )
151
 
152
  demo.launch()