feelling 1.0.4
A lightweight Python library for musical emotion analysis
Requires Python: >=3.6

# feel: Python Library for Musical Emotion Analysis

`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).

---

## 🚀 Installation

Install via PyPI:

```bash
pip install feelling
```

## 🎵 Supported Formats

* WAV
* FLAC
* MP3
* M4A/AAC
* OGG/OPUS

*(FFmpeg must be installed and in your PATH for MP3/AAC/OGG/OPUS support.)*

---

## 🔍 How It Works

1. **Load Audio**: Uses `soundfile` or `pydub` (with FFmpeg) to read and resample to 22.05 kHz mono.
2. **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
3. **Normalize**: Feature values are min–max normalized within the file.
4. **Score Emotions**: A weighted sum over features for each emotion (sadness, happiness, grandeur, etc.).

Weights for each emotion are configurable in `EMOTION_WEIGHTS`.

---

## ⚙️ Quickstart

```python
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).

---

## 🎨 Customizing Emotions

You can add, remove, or adjust emotion weights in your local `feel.py` before calling `analyze`. Example:

```python
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
}
```

---

## 📝 License

MIT © \Mr. Mohammad Taha Gorji