-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path01_mix_analysis.py
More file actions
156 lines (122 loc) · 4.9 KB
/
01_mix_analysis.py
File metadata and controls
156 lines (122 loc) · 4.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env python3
"""
01_mix_analysis.py - Analyze Your Mix with the Tonn API
This example demonstrates how to analyze a mixed or mastered audio track
using the Tonn API's mix diagnosis feature (powered by Mix Check Studio).
What this does:
- Uploads your audio file to cloud storage
- Analyzes loudness, dynamic range, stereo field, and tonal balance
- Provides actionable feedback for improving your mix
Usage:
python 01_mix_analysis.py <audio_file> <musical_style> [--is-master]
Example:
python 01_mix_analysis.py my_track.wav POP --is-master
python 01_mix_analysis.py demo.mp3 ROCK
Musical styles: ROCK, POP, ELECTRONIC, HIPHOP_GRIME, ACOUSTIC, ROCK_INDIE, etc.
"""
import sys
import os
import argparse
# Add the parent directory to path so we can import shared modules
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from shared import TonnClient
def print_diagnosis_results(diagnosis: dict) -> None:
"""Pretty-print the mix diagnosis results."""
if not isinstance(diagnosis, dict):
print("No valid diagnosis results found.")
return
print("\n" + "=" * 60)
print("MIX DIAGNOSIS RESULTS")
print("=" * 60)
# Completion info
print(f"\nCompletion Time: {diagnosis.get('completion_time', 'N/A')}")
if diagnosis.get('error'):
print(f"⚠️ Error: {diagnosis.get('info', 'Unknown error')}")
return
# Payload details
payload = diagnosis.get("payload", {})
if payload:
print("\n--- Technical Details ---")
# Key metrics
metrics = [
("Bit Depth", payload.get("bit_depth")),
("Sample Rate", payload.get("sample_rate")),
("Integrated Loudness (LUFS)", payload.get("integrated_loudness_lufs")),
("Peak Loudness (dBFS)", payload.get("peak_loudness_dbfs")),
("Clipping", payload.get("clipping")),
("Stereo Field", payload.get("stereo_field")),
("Mono Compatible", payload.get("mono_compatible")),
("Phase Issues", payload.get("phase_issues")),
]
for name, value in metrics:
if value is not None:
print(f" {name}: {value}")
# Mastering evaluation
if payload.get("if_master_drc"):
print(f"\n Master DRC Evaluation: {payload.get('if_master_drc')}")
if payload.get("if_master_loudness"):
print(f" Master Loudness Evaluation: {payload.get('if_master_loudness')}")
# Summary
summary = payload.get("summary", {})
if summary:
print("\n--- Recommendations ---")
for idx, (key, value) in enumerate(summary.items(), 1):
print(f" {idx}. {value}")
print("\n" + "=" * 60)
def main():
parser = argparse.ArgumentParser(
description="Analyze a mix/master using the Tonn API",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
python 01_mix_analysis.py track.wav POP
python 01_mix_analysis.py master.mp3 ROCK --is-master
python 01_mix_analysis.py demo.flac ELECTRONIC
Musical Styles:
ROCK, POP, ELECTRONIC, HIPHOP_GRIME, ACOUSTIC, ROCK_INDIE,
SINGER_SONGWRITER, JAZZ, CLASSICAL, and more.
"""
)
parser.add_argument("input_file", help="Path to audio file (.mp3, .wav, .flac)")
parser.add_argument("musical_style", help="Musical style (e.g., ROCK, POP)")
parser.add_argument("--is-master", action="store_true",
help="Flag if the input is a mastered track")
args = parser.parse_args()
# Validate input file exists
if not os.path.isfile(args.input_file):
print(f"Error: File not found: {args.input_file}")
sys.exit(1)
# Initialize client
client = TonnClient()
# Upload the file
print(f"\n📤 Uploading {os.path.basename(args.input_file)}...")
readable_url = client.upload_local_file(args.input_file)
if not readable_url:
print("Failed to upload file. Exiting.")
sys.exit(1)
# Build the analysis payload
payload = {
"mixDiagnosisData": {
"audioFileLocation": readable_url,
"musicalStyle": args.musical_style.upper(),
"isMaster": args.is_master
}
}
# Run the analysis
print(f"\n🔍 Analyzing your {'master' if args.is_master else 'mix'}...")
response = client.post("/mixanalysis", payload)
if not response:
print("Analysis failed. Check your API key and try again.")
sys.exit(1)
# Display results
if response.get("error"):
print(f"❌ Error: {response.get('message', 'Unknown error')}")
sys.exit(1)
print(f"✅ {response.get('message', 'Analysis complete')}")
diagnosis_results = response.get("mixDiagnosisResults")
if diagnosis_results:
print_diagnosis_results(diagnosis_results)
else:
print("No diagnosis results in response.")
if __name__ == "__main__":
main()