
ย
ย
๐ก ์ค๋์ ์คํ ์ฃผ์
๊ฐ์ ์๋ ์๋ ์์ง๋ง, ๋ฆฌ๋ฌ๋ ์๋ค.
๊ธฐ์จ์ ๋น ๋ฅด๊ณ ๋ฐ์ ์์ผ๋ก, ์ฌํ์ ๋๋ฆฌ๊ณ ๋ฎ์ ์์ผ๋ก ์ธ๋ฆฐ๋ค.
์ค๋์ ๋ชฉํ๋ AI ๊ฐ์ ์ โ์๋ฆฌ ๋ฐ์ดํฐโ๋ก ๋ณํํด ์์
์ฒ๋ผ ๋ค๋ ค์ฃผ๋ ์ฝ๋๋ฅผ ๋ง๋๋ ๊ฒ์ด๋ค.
๐งฐ ์ฌ์ฉํ ๋๊ตฌ
| ๋๊ตฌ | ์ญํ | ์ค๋ช |
|---|---|---|
| ๐ง numpy | ์ฌ์ธํ ์ ์์ฑ | ๊ฐ์ ์ ์๋ฅผ ์ฃผํ์(frequency)๋ก ๋ณํํ์ฌ ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ง๋ญ๋๋ค. |
| ๐๏ธ pydub | ์ค๋์ค ํ์ผ ์์ฑ | NumPy๋ก ๋ง๋ ์ ๋ฐ์ดํฐ๋ฅผ ์ค์ .wav ํ์ผ๋ก ์ ์ฅํ๊ฑฐ๋ ์ฌ์ํฉ๋๋ค. |
| ๐ง openai | ๊ฐ์ ๋ถ์ | ์ ๋ ฅ๋ ๋ฌธ์ฅ์ ๊ฐ์ ๊ฐ๋(0~1)๋ฅผ ์ถ์ถํ์ฌ ์๋ฆฌ ๋งคํ์ ์ฌ์ฉํฉ๋๋ค. |
| ๐ป VS Code | ๊ฐ๋ฐ ํ๊ฒฝ | ์คํ ์ ์ฉ ํธ์ง๊ธฐ. ์์ฑ ํ์ผ์ ๊ฐ์ ํด๋์ ์ ์ฅ๋ฉ๋๋ค. |
๐งฉ 1๏ธโฃ ํ๊ฒฝ ์ธํ
pip install numpy pydub openai
โ ๏ธ pydub์ ๋ด๋ถ์ ์ผ๋ก ffmpeg๋ฅผ ์ฌ์ฉํ๋ฏ๋ก,
์์คํ
์ ffmpeg๊ฐ ์ค์น๋์ด ์์ด์ผ ํฉ๋๋ค.
# macOS
brew install ffmpeg
# Windows (choco ์ฌ์ฉ)
choco install ffmpeg
๐ง 2๏ธโฃ ๊ฐ์ ์ ์๋ฅผ ๋ฐ์์ค๊ธฐ
OpenAI API๋ฅผ ์ฌ์ฉํด ๋ฌธ์ฅ์ ๊ฐ์ ์ ์์นํํฉ๋๋ค.
import openai
openai.api_key = "YOUR_API_KEY"
def analyze_emotion(sentence):
prompt = f"'{sentence}' ๋ฌธ์ฅ์ ๊ฐ์ ์ 0~1 ์ฌ์ด์ ์์น๋ก ํํํด์ค. 1์ ๋งค์ฐ ๊ธ์ , 0์ ๋งค์ฐ ๋ถ์ ."
res = openai.ChatCompletion.create(
model="gpt-4-turbo",
messages=[{"role":"user","content":prompt}]
)
return float(res.choices[0].message.content.strip())
score = analyze_emotion("์ค๋์ ํ์ด์ด ๋ฐ๋ปํ๊ณ ๋ง์์ด ๊ฐ๋ฒผ์์.")
print("๊ฐ์ ์ ์:", score)
์ถ๋ ฅ ์์:๊ฐ์ ์ ์: 0.87
โ ๊ฐ์ ์ด ๋ฐ๊ณ ๊ธ์ ์ ์ผ์๋ก ๋์ ์์น๊ฐ ๋ฐํ๋ฉ๋๋ค.
๐ต 3๏ธโฃ ๊ฐ์ ์ ์๋ฅผ ์๋ฆฌ๋ก ๋ณํํ๊ธฐ
๊ฐ์ ์ ์์ ๋ฐ๋ผ ์ฃผํ์๋ฅผ ๋ฐ๊ฟ๋ด
์๋ค.
๊ธฐ๋ณธ ์์ 440Hz(A4), ๊ฐ์ ์ ์๋ก ์ ๋์ด๋ฅผ ์กฐ์ ํฉ๋๋ค.
import numpy as np
from pydub import AudioSegment
from pydub.playback import play
def emotion_to_tone(score):
duration = 1500 # ms
base_freq = 440 # Hz
freq = base_freq + (score - 0.5) * 400 # ๊ฐ์ ์ ๋ฐ๋ผ ๋๋ฎ์ด ์กฐ์
volume = -10 + (score * 10) # dB ์กฐ์
sample_rate = 44100
t = np.linspace(0, duration / 1000, int(sample_rate * duration / 1000), False)
wave = np.sin(freq * t * 2 * np.pi)
audio = (wave * 32767).astype(np.int16)
sound = AudioSegment(audio.tobytes(), frame_rate=sample_rate, sample_width=2, channels=1)
sound = sound + volume
return sound
tone = emotion_to_tone(0.87)
play(tone)
๐ ์ถ๋ ฅ ๊ฒฐ๊ณผ: ๋ฐ๊ณ ๋์ ์์ด ์ฝ 1.5์ด ๋์ ์ฌ์๋ฉ๋๋ค.
๊ฐ์ ์ด ์ด๋์์ง์๋ก ์์ ๋ฎ์์ง๊ณ ๊ธธ์ด๋ ์งง์์ง๋๋ค.
๐ผ 4๏ธโฃ ๊ฐ์ ์ผ๊ธฐ๋ฅผ ์๋ฆฌ๋ก ๋จ๊ธฐ๊ธฐ
ํ๋ฃจ์ ๊ฐ์ ๊ธฐ๋ก์ ์ฌ๋ฌ ๋ฌธ์ฅ์ผ๋ก ์
๋ ฅํ๋ฉด,
๊ฐ์ ์ ํ๋ฆ์ ์ ๋์ด๋ก ์ฐ๊ฒฐํ ์ ์์ต๋๋ค.
sentences = [
"์์นจ ๊ณต๊ธฐ๊ฐ ์์พํ๋ค.",
"ํ์๋ ์กฐ๊ธ ์ง๋ฃจํ์ง๋ง ๊ด์ฐฎ์๋ค.",
"์ ๋
์ ๊ฐ์กฑ๊ณผ ์์ผ๋ฉฐ ์์ฌํ๋ค."
]
track = AudioSegment.silent(duration=0)
for s in sentences:
score = analyze_emotion(s)
sound = emotion_to_tone(score)
track += sound
track.export("mood_sound.wav", format="wav")
print("๐ถ ๊ฐ์ ์ผ๊ธฐ ์ฌ์ด๋ ํ์ผ ์ ์ฅ ์๋ฃ!")
๐พ ๊ฒฐ๊ณผ: mood_sound.wav
โ ํ๋ฃจ์ ๊ฐ์ ์ด ์ฐ์๋ ์์ผ๋ก ๋ณํ๋ ํ์ผ์ด ์์ฑ๋ฉ๋๋ค.
๐ง 5๏ธโฃ ์คํ ํ๊ธฐ
AI๋ ๊ฐ์ ์ ์ฝ๊ณ , ํ์ด์ฌ์ ๊ทธ๊ฒ์ ๋ค๋ ค์คฌ๋ค.
๊ธฐ์จ์ ๋ง์ ๋(Do), ์ฌํ์ ๋ฎ์ ์(Sol)์ฒ๋ผ ์ธ๋ฆฐ๋ค.
์ด๊ฑด ๋จ์ํ ์ฌ์ด๋ ์คํ์ด ์๋๋ผ,
๋ฐ์ดํฐ๊ฐ ๊ฐ์ ์ ์ธ์ด๋ฅผ ์ป์ ์๊ฐ์ด์๋ค.
“์์ ์ ๊ฐ์ ์ ๋ฒ์ญํ ๋ฐ์ดํฐ๋ค.
AI๋ ๊ทธ ๋ฒ์ญ๊ฐ์ผ ๋ฟ, ๊ฐ์ ์ ์ฃผ์ธ์ ์ฌ์ ํ ์ธ๊ฐ์ด๋ค.”
๊ธฐ์ ์ด ์ธ๊ฐ์ ๊ฐ์ ์ ๋์ฒดํ๋ ๊ฒ ์๋๋ผ,
๊ทธ ๊ฐ์ ์ โ์๋ก์ด ํ์โ์ผ๋ก ํํํ ์ ์๊ฒ ๋๋ ๊ฒ โ
์ด๊ฒ ๋ชฝ๋ธ์ด ์ถ๊ตฌํ๋ ๋ฐ์ด๋ธ์ฝ๋ฉ์ด๋ค.
๐ช ๋ค์ ์คํ ์๊ณ
โ๊ฐ์ ์ ๋์ โ ํฅ์ผ๋ก ๊ธฐ์ตํ๋ ์ฝ๋โ
๋ค์ ์คํ์์๋ ํ
์คํธ ๊ฐ์ โ ํฅ ๋ฐ์ดํฐ โ ๋์งํธ ์ผ์๋ก ์ด์ด์ง๋
ใ๋ฐ์ด๋ธ์ฝ๋ฉ #4: Scent of Codeใ ๋ฅผ ์ค๋นํฉ๋๋ค.
๐ ํด์ํ๊ทธ
#๋ชฝ๋ธ #๋ฐ์ด๋ธ์ฝ๋ฉ #AI์์ ์คํ #SoundOfMood #๊ฐ์ ์ฌ์ด๋ #ํ์ด์ฌ์คํ #pydub #numpy #openai #AI์ฐฝ์