Tutorial - Post-Production Audio Processing¶
The Tonn API provides post-production endpoints for dialogue enhancement, delivery format mastering, and loudness compliance checking. This tutorial walks through each workflow with Python and cURL examples.
Prerequisites¶
- A valid API key (see Getting Started)
- Audio files uploaded via
/upload(see the Mixing Tutorial for upload details) - Python with
requestsinstalled, or cURL
Base URL:
https://tonn.roexaudio.com
All requests require the X-API-Key header for authentication.
Dialogue Enhancement¶
Enhance dialogue clarity and intelligibility in a single track with noise reduction and level optimisation.
Step 1: Create a Preview Task¶
import requests
API_KEY = "your-api-key"
BASE_URL = "https://tonn.roexaudio.com"
response = requests.post(
f"{BASE_URL}/postprod/dialogue-enhancement/preview",
headers={"X-API-Key": API_KEY},
json={
"postProdData": {
"trackData": [
{
"trackURL": "https://your-uploaded-audio-url/dialogue.wav",
"trackType": "DIALOGUE_MAIN",
"dialogueEnhancementMode": "ENHANCE"
}
],
"sampleRate": 48000,
"webhookURL": "https://your-server.com/webhook"
}
}
)
result = response.json()
task_id = result["postprodTaskId"]
print(f"Task created: {task_id}")
Track types: DIALOGUE_MAIN, DIALOGUE_SECONDARY, ADR, VOICEOVER_LP, VOICEOVER_HP
Enhancement modes:
| Mode | Description |
|---|---|
PRESERVE |
Minimal processing, preserves natural sound |
ENHANCE |
Standard clarity boost |
AD_ENHANCED |
Aggressive enhancement for commercials |
SOCIAL_MEDIA_VO |
Mobile-optimised voice-over for short-form video |
Step 2: Retrieve the Preview¶
Once your webhook fires (or after polling), retrieve the preview:
response = requests.post(
f"{BASE_URL}/postprod/dialogue-enhancement/retrievepreview",
headers={"X-API-Key": API_KEY},
json={
"postProdData": {
"postprodTaskId": task_id
}
}
)
if response.status_code == 200:
preview = response.json()
print("Preview ready:", preview)
elif response.status_code == 202:
print("Still processing, try again later")
Step 3: Retrieve the Final Result¶
When you are satisfied with the preview, retrieve the final full-length result. This charges credits.
response = requests.post(
f"{BASE_URL}/postprod/dialogue-enhancement/retrieve",
headers={"X-API-Key": API_KEY},
json={
"postProdData": {
"postprodTaskId": task_id
}
}
)
if response.status_code == 200:
final = response.json()
print("Final result:", final)
cURL equivalent:
curl -X POST https://tonn.roexaudio.com/postprod/dialogue-enhancement/retrieve \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"postProdData": {
"postprodTaskId": "your-task-id"
}
}'
Delivery Format Mastering¶
Master audio to meet loudness and peak standards for a specific delivery format.
Delivery Formats¶
| Format | Target LUFS | Max True Peak | Use case |
|---|---|---|---|
FILM |
-24 LUFS | -2 dBTP | Cinema |
TV |
-23 LUFS | -2 dBTP | Television (EBU R128) |
STREAMING |
-27 LUFS | -2.3 dBTP | Streaming platforms |
YOUTUBE |
-14 LUFS | -1 dBTP | YouTube |
BROADCAST |
-23 LUFS | -1 dBTP | Strict EBU R128 broadcast |
ADMIX |
-23 LUFS | -1 dBTP | Advertising |
PODCAST |
-16 LUFS | -1 dBTP | Podcast platforms |
SOCIAL_MEDIA |
-14 LUFS | -1 dBTP | Instagram Reels / TikTok / Shorts |
Step 1: Create a Preview Task¶
response = requests.post(
f"{BASE_URL}/postprod/delivery-mastering/preview",
headers={"X-API-Key": API_KEY},
json={
"postProdData": {
"trackData": [
{
"trackURL": "https://your-uploaded-audio-url/mix.wav"
}
],
"deliveryFormat": "BROADCAST",
"sampleRate": 48000,
"webhookURL": "https://your-server.com/webhook"
}
}
)
result = response.json()
task_id = result["postprodTaskId"]
Step 2: Retrieve the Preview¶
response = requests.post(
f"{BASE_URL}/postprod/delivery-mastering/retrievepreview",
headers={"X-API-Key": API_KEY},
json={
"postProdData": {
"postprodTaskId": task_id
}
}
)
Step 3: Retrieve the Final Result¶
Charges credits and returns the mastered audio with compliance data.
response = requests.post(
f"{BASE_URL}/postprod/delivery-mastering/retrieve",
headers={"X-API-Key": API_KEY},
json={
"postProdData": {
"postprodTaskId": task_id
}
}
)
if response.status_code == 200:
final = response.json()
print(f"Measured LUFS: {final.get('measuredLUFS')}")
print(f"True Peak: {final.get('truePeakDb')} dBTP")
print(f"Meets spec: {final.get('meetsLoudnessSpec')}")
Loudness Compliance Check¶
Non-destructive analysis that measures loudness, true peak, dynamic range, and compliance against a target delivery format without altering the audio.
Step 1: Submit a Loudness Check¶
response = requests.post(
f"{BASE_URL}/postprod/loudness-check",
headers={"X-API-Key": API_KEY},
json={
"postProdData": {
"trackData": [
{
"trackURL": "https://your-uploaded-audio-url/final_mix.wav"
}
],
"deliveryFormat": "STREAMING",
"webhookURL": "https://your-server.com/webhook"
}
}
)
result = response.json()
task_id = result["postprodTaskId"]
Step 2: Retrieve Results¶
Charges credits and returns loudness measurements and compliance flags.
response = requests.post(
f"{BASE_URL}/postprod/loudness-check/retrieve",
headers={"X-API-Key": API_KEY},
json={
"postProdData": {
"postprodTaskId": task_id
}
}
)
if response.status_code == 200:
results = response.json()
print(f"Integrated Loudness: {results.get('measuredLUFS')} LUFS")
print(f"True Peak: {results.get('truePeakDb')} dBTP")
print(f"Dynamic Range: {results.get('dynamicRangeLU')} LU")
print(f"Meets Loudness Spec: {results.get('meetsLoudnessSpec')}")
print(f"Meets Peak Spec: {results.get('meetsPeakSpec')}")
cURL equivalent:
curl -X POST https://tonn.roexaudio.com/postprod/loudness-check \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"postProdData": {
"trackData": [{"trackURL": "https://your-uploaded-audio-url/final_mix.wav"}],
"deliveryFormat": "BROADCAST",
"webhookURL": "https://your-server.com/webhook"
}
}'
Webhooks¶
All post-production endpoints accept a webhookURL parameter. When processing completes, a POST request is sent to your webhook URL with the task ID and status. This is the recommended approach over polling.
Response Codes¶
| Code | Meaning |
|---|---|
| 200 | Success -- results are ready |
| 202 | Still processing -- try again later |
| 400 | Bad request -- check your payload |
| 401 | Invalid API key |
| 402 | Insufficient credits (final retrieve endpoints only) |
| 404 | Task not found |
Next Steps¶
- See the API Reference for full endpoint schemas
- See the Getting Started guide for account setup and credits
- See the FAQ for upload limits, supported formats, and pricing