feel is a lightweight Python library for analyzing a music file and scoring it across multiple emotions based on its acoustic features (pitch, rhythm, timbre).
Install via PyPI:
pip install feelling- WAV
- FLAC
- MP3
- M4A/AAC
- OGG/OPUS
(FFmpeg must be installed and in your PATH for MP3/AAC/OGG/OPUS support.)
-
Load Audio: Uses
soundfileorpydub(with FFmpeg) to read and resample to 22.05 kHz mono. -
Extract Features: Computes:
- Harmonic vs. percussive energy ratio
- Chroma (CQT) to detect minor/major ratio
- Tempo (beats per minute)
- Spectral descriptors (centroid, bandwidth, contrast, rolloff, flatness)
- Zero-crossing rate (ZCR)
- Root-mean-square (RMS) loudness
-
Normalize: Feature values are min–max normalized within the file.
-
Score Emotions: A weighted sum over features for each emotion (sadness, happiness, grandeur, etc.).
Weights for each emotion are configurable in EMOTION_WEIGHTS.
from feelling import analyze
# Analyze an audio file and get emotion scores
scores = analyze("path/to/song.mp3")
print(scores)
# Example output:
{'amazement': 2.785994294009202,
'anger': 2.7061781529298923,
'awe': 2.3857337980174704,
'bittersweet': -0.6897889961401367,
'brooding': -1.2310171365296803,
'calmness': -1.3223295386507186,
'compassion': 0.8462746872436658,
'contemplation': -0.6982909427247976,
'courage': 2.02148080255978,
'despair': -2.231273017589515,
'devotion': 0.6195735408259397,
'ecstasy': 3.1549486543435767,
'empathy': 0.5456626971919932,
'energy': 2.7875557099155377,
'euphoria': 3.4885498522529366,
'excitement': 2.3111535163286896,
'fear': 1.376430927354388,
'fun': 2.5987931168715916,
'fury': 2.647916600269525,
'gloom': -2.528004024674664,
'grandeur': 2.413186509472432,
'guilt': -2.0240664318416393,
'happiness': 2.019107444540511,
'hope': 1.8475886363524776,
'intimacy': 0.8485076464346826,
'joy': 2.847461883314458,
'jubilation': 2.7760478539781217,
'longing': -1.1097125270242696,
'love': 1.5902762628566427,
'melancholy': -1.6859296441216043,
'mourning': -2.0619032976192506,
'mysticism': -0.08503173099393924,
'nostalgia': -0.9471086633393663,
'optimism': 2.1649828698552853,
'peace': -1.0088574401582806,
'playfulness': 2.469039451504274,
'pride': 1.7142282816425052,
'relief': -1.2378913124481465,
'reverence': 2.0027256095964767,
'sadness': -1.4695416250468998,
'serenity': -1.2599763350028974,
'shame': -1.716638007519969,
'solitude': -1.0641904277010628,
'surprise': 3.0351611656705053,
'tenderness': 0.9212167712326097,
'tension': 1.8677738672595334,
'tranquility': -1.383235730007885,
'wistfulness': -1.064112344330448,
'yearning': -1.5448817048229317,
'zeal': 2.4694397366889294}Each score is a floating-point value (higher = stronger presence of that emotion).
You can add, remove, or adjust emotion weights in your local feel.py before calling analyze. Example:
from feel import EMOTION_WEIGHTS
# Add a new emotion "mystical"
EMOTION_WEIGHTS['mystical'] = {
'minor_ratio': 0.0,
'tempo': -0.2,
'centroid': 0.1,
# ... specify all 10 features
}MIT © \Mr. Mohammad Taha Gorji