T.ME/BIBIL_0DAY
CasperSecurity


Server : Apache/2
System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64
User : gositeme ( 1004)
PHP Version : 8.2.29
Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
Directory :  /home/gositeme/.cursor-server/data/User/History/-7d274db2/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/.cursor-server/data/User/History/-7d274db2/DM04.md
# BPM and Key Search Implementation

This document explains the BPM (Beats Per Minute) and musical key detection and search functionality.

## Overview

The system now supports:
- **BPM Detection**: Automatic detection of beats per minute from audio files
- **Key Detection**: Automatic detection of musical key (e.g., "C major", "A minor")
- **Camelot Wheel**: DJ-friendly Camelot wheel notation (e.g., "8B", "1A")
- **Global Search**: Search tracks by BPM range and/or musical key

## Database Schema

New columns added to `music_tracks` table:
- `bpm` (INT) - Beats per minute (40-300 range)
- `musical_key` (VARCHAR(20)) - Musical key (e.g., "C major", "A minor")
- `camelot_key` (VARCHAR(5)) - Camelot wheel notation (e.g., "8B", "1A")

All columns are indexed for fast searching.

## Setup Instructions

### Step 1: Run Database Migration

Visit: `https://soundstudiopro.com/migrations/add_bpm_key_columns.php`

This will:
- Add `bpm`, `musical_key`, and `camelot_key` columns
- Create indexes for fast searching
- Create composite index for BPM+key searches

### Step 2: Extract Existing Data

Visit: `https://soundstudiopro.com/utils/extract_bpm_key_from_metadata.php`

This will:
- Extract BPM and key from existing metadata JSON
- Populate the new dedicated columns
- Process all completed tracks

**Note**: To force re-extraction (overwrite existing values), add `?force=1` to the URL.

### Step 3: Verify

Check how many tracks have BPM/key data:
```sql
SELECT 
    COUNT(*) as total,
    COUNT(bpm) as with_bpm,
    COUNT(musical_key) as with_key,
    COUNT(CASE WHEN bpm IS NOT NULL AND musical_key IS NOT NULL THEN 1 END) as complete
FROM music_tracks 
WHERE status = 'complete';
```

## How It Works

### Client-Side Analysis (Existing Tracks)

When a user views a track page (`track.php`), the JavaScript audio analyzer:
1. Loads the audio file
2. Analyzes it using Web Audio API
3. Detects BPM and musical key
4. Sends results to `/api/save_audio_analysis.php`
5. API saves to both metadata JSON and dedicated columns

### New Track Creation

When new tracks are created:
- BPM/key may be provided in the callback metadata
- If not, client-side analysis runs on first view
- Data is stored in both metadata JSON and dedicated columns

## Search API Usage

### Basic Text Search (unchanged)
```
GET /api_global_search.php?q=house&limit=20
```

### Search by BPM Range
```
GET /api_global_search.php?min_bpm=120&max_bpm=140&limit=20
```

### Search by Musical Key
```
GET /api_global_search.php?key=C major&limit=20
```

### Search by Camelot Key (DJ-friendly)
```
GET /api_global_search.php?camelot=8B&limit=20
```

### Combined Search
```
GET /api_global_search.php?q=techno&min_bpm=130&max_bpm=150&key=A minor&limit=20
```

### Search by BPM/Key Only (no text query)
```
GET /api_global_search.php?min_bpm=128&max_bpm=132&limit=50
```

## API Parameters

| Parameter | Type | Description | Example |
|-----------|------|-------------|---------|
| `q` | string | Text search query (optional if filters provided) | `"techno"` |
| `min_bpm` | integer | Minimum BPM (40-300) | `120` |
| `max_bpm` | integer | Maximum BPM (40-300) | `140` |
| `key` | string | Musical key (case-insensitive) | `"C major"` or `"a minor"` |
| `camelot` | string | Camelot wheel notation | `"8B"` or `"1A"` |
| `limit` | integer | Max results (default: 10, max: 20) | `20` |

## Response Format

The API returns tracks with BPM and key data included:

```json
{
  "tracks": [
    {
      "id": 123,
      "title": "Techno Track",
      "bpm": 128,
      "musical_key": "A minor",
      "camelot_key": "8A",
      "artist_name": "DJ Name",
      ...
    }
  ],
  ...
}
```

## Camelot Wheel Reference

The Camelot wheel is used by DJs for harmonic mixing. Compatible keys are adjacent:

- **Same number, different letter** (e.g., 8A ↔ 8B) - Perfect match
- **Adjacent numbers, same letter** (e.g., 8A ↔ 7A or 9A) - Good match
- **Adjacent numbers, different letter** (e.g., 8A ↔ 7B or 9B) - Acceptable

Example: A track in 8B (C major) mixes well with:
- 8A (A minor) - Same number
- 7B (F major) or 9B (G major) - Adjacent numbers, same letter
- 7A (D minor) or 9A (E minor) - Adjacent numbers, different letter

## Frontend Integration

To add BPM/Key filters to your search UI:

```javascript
// Example search with BPM filter
async function searchTracks(query, minBPM, maxBPM, key) {
    const params = new URLSearchParams();
    if (query) params.append('q', query);
    if (minBPM) params.append('min_bpm', minBPM);
    if (maxBPM) params.append('max_bpm', maxBPM);
    if (key) params.append('key', key);
    params.append('limit', 20);
    
    const response = await fetch(`/api_global_search.php?${params}`);
    return await response.json();
}
```

## Maintenance

### Re-analyzing Tracks

If you need to re-analyze tracks (e.g., after improving the analyzer):
1. Visit `/utils/extract_bpm_key_from_metadata.php?force=1`
2. Or manually trigger client-side analysis by visiting track pages

### Batch Processing New Tracks

For server-side batch processing (if needed), you can:
1. Create a cron job that processes tracks without BPM/key
2. Use the existing client-side analyzer via headless browser
3. Or integrate a server-side audio analysis library

## Performance Notes

- Indexes on `bpm`, `musical_key`, and `camelot_key` ensure fast searches
- Composite index on `(bpm, musical_key)` optimizes combined searches
- JSON metadata is still stored for backward compatibility
- Dedicated columns avoid JSON parsing on every search query

## Troubleshooting

### No BPM/Key Data

1. Check if migration ran: `SHOW COLUMNS FROM music_tracks LIKE 'bpm'`
2. Run extraction script: `/utils/extract_bpm_key_from_metadata.php`
3. Check metadata has BPM/key: `SELECT metadata FROM music_tracks WHERE id = ?`

### Search Not Working

1. Verify columns exist and have indexes
2. Check API logs for SQL errors
3. Test with simple query: `/api_global_search.php?min_bpm=120&max_bpm=140`

### Inaccurate BPM/Key

- Client-side analysis may vary slightly
- Higher confidence scores indicate more reliable results
- Consider server-side analysis for production-critical accuracy


CasperSecurity Mini