The 1908 Jack Norworth and Albert Von Tilzer song “Take Me Out to the Ball Game” has been a classic staple across ballparks becoming synonymous with America’s favorite pastime. At over 114 years old, the original version of “Take Me Out to the Ball Game” was recorded on a two-minute Edison Wax Cylinder by singer and performer Edward Meeker, quickly becoming a beloved classic. With the baseball season getting underway this April 7th we thought it about time to dust off the gloves, pick up our bats, step up to our Python environments, and get to work algorithmically remastering the classic anthem with the Dolby.io Music Mastering API.
What is Music Mastering?
Typically performed by audio engineers, Mastering is a labor-intensive post-production process usually applied as the last step in creating a song and is the final polish that takes a track from good to great. Because “Take Me Out to the Ball Game” was recorded and produced in 1908 the mastering and post-production technology was very limited and hence it could be interesting to explore the impact of applying a music mastering algorithm on the original recording, and the effect that has on the palatability of the track.
Picking a Version:
Before we can get started remastering “Take Me Out to the Ball Game”, we first need to pick a version of the song. Whilst we often hear the catchy tune played during the middle of the seventh inning, that version isn’t the original and is subject to copyright protection. For this project, we will be using the 1908 version found here, as it is now available in the public domain and free to use. Unfortunately, the highest-quality version of the 1908 song is stored as an MP3. Whilst this works with the API, Free Lossless Audio Codec (FLAC) or other lossless file types are preferred as they produce the best results during the mastering post-production process.
The AI Music Mastering Free Trial
With our song in hand, it’s time to introduce the tool that will be doing the majority of the heavy lifting. The Dolby.io Music Mastering API is a music enhancement tool that allows users to programmatically master files via a number of sound profiles specific to certain genres and styles. The API isn’t free, however, the company offers trial credits if you sign up and additional trial credits if you add your credit card to the platform.
For this project, the trial tier will be sufficient which is available if you sign up here.
Once you have created an account and logged in, navigate over to the applications tab, select “my_first_app”, and locate your Media APIs API Key.
It’s important to note that all Dolby.io media APIs adhere to the REST framework, meaning they are language agnostic. For the purposes of this project, I will be using the tool in Python, however, it works in any other language.
Adding it to the Dolby.io Server
To utilize the Music Mastering API we first need to store the MP3 file on the cloud. This can be done with either a cloud service provider such as AWS, or you can use the Dolby.io Media Storage platform. For simplicity, we will use the Dolby.io platform which can be accessed via a REST API call.
To get started we need to import the Python “Requests” package and specify a path to the MP3 file on our local machine.
import requests #Requests is useful for making HTTP requests and interacting with REST APIs
file_path = "Take-Me-Out-to-the-Ball-Game.mp3"
Next, we need to specify the URL we want the Requests package to interact with, specifically the Dolby.io Media Input address. In addition to the input URL, we also need to format a header that will authenticate our request to the Dolby.io server with our API key.
url = "https://api.dolby.com/media/input"
headers = {
"x-api-key": "YOUR DOLBY.IO MEDIA API KEY",
"Content-Type": "application/json",
"Accept": "application/json",
}
Finally, we need to format a body that specifies the name we want to give our file once it is added to the server.
body = {
"url": "dlb://input-example.mp3",
}
With the URL, Head, and Body all formatted correctly we can use the Requests package to create a pre-signed URL to which we can upload our MP3 file to.
response = requests.post(url, json=body, headers=headers)
response.raise_for_status()
presigned_url = response.json()["url"]
print("Uploading {0} to {1}".format(file_path, presigned_url))
with open(file_path, "rb") as input_file:
requests.put(presigned_url, data=input_file)
Starting an AI Music Mastering Job
Once the audio file has been moved to the cloud we can begin calling a mastering job. The Music Mastering API includes a number of predefined “profiles” which match up to a selection of audio genres such as Hip Hop or Rock. For the best results, a Rock song should be mastered with the Rock profile, however, the process of picking a profile can require a bit of experimentation.
Because matching creative intent with different sound profiles can take a few trials the API offers a “preview version” where you can master a 30 seconds segment of a song with 3 different profiles. We format the body of this request to include this information as well as when we want the segment to begin.
body = {
"inputs": [
{"source": "dlb://input-example.mp3", "segment": {"start": 36, "duration": 30}} #36 seconds is the start of the iconic chorus.
],
"outputs": [
{
"destination": "dlb://example-master-preview-l.mp3",
"master": {"dynamic_eq": {"preset": "l"}} #Lets master with the Vocal profile
},
{
"destination": "dlb://example-master-preview-m.mp3",
"master": {"dynamic_eq": {"preset": "m"}} #Lets master with the Folk profile
},
{
"destination": "dlb://example-master-preview-n.mp3",
"master": {"dynamic_eq": {"preset": "n"}} #Lets master with the Classical profile
}
]
}
The Header stays the same as the one we used to upload the file to the Dolby.io Server and the URL changes to match the Music Mastering endpoint.
url = "https://api.dolby.com/media/master/preview"
headers = {
"x-api-key": "YOUR DOLBY.IO MEDIA API KEY",
"Content-Type": "application/json",
"Accept": "application/json",
}
We can use the Requests package to deliver our profile selections and start the mastering job.
response = requests.post(url, json=body, headers=headers)
response.raise_for_status()
print(response.json())
job_id = response.json()["job_id"]
This process can take a minute to complete. To check the status of the job we can format another request to the same URL with the Job_ID included in the body to check the progress of the master.
url = "https://api.dolby.com/media/master/preview"
headers = {
"x-api-key": "YOUR DOLBY.IO MEDIA API KEY",
"Content-Type": "application/json",
"Accept": "application/json",
}
params = {"job_id": job_id}
response = requests.get(url, params=params, headers=headers)
response.raise_for_status()
print(response.json())
The response from the request outputs the progress of the job between 0% and 100%.
Downloading the Mastered File
With our file mastered it’s time to download the three master previews so we can hear the difference. The workflow for downloading files mirrors that of how the rest of the Dolby.io APIs work. Much like uploading a file or starting a job, we format a header with our API key and a body that points to the mastering output on the Dolby.io server.
import shutil #File operations package useful for downloading files from a server.
url = "https://api.dolby.com/media/output"
headers = {
"x-api-key": api_key,
"Content-Type": "application/json",
"Accept": "application/json",
}
for profile in ["l","m","n"]:
output_path = "out/preview-" + profile + ".mp3"
preview_url = "dlb://example-master-preview-" + profile + ".mp3"
args = {"url": preview_url}
with requests.get(url, params=args, headers=headers, stream=True) as response:
response.raise_for_status()
response.raw.decode_content = True
print("Downloading from {0} into {1}".format(response.url, output_path))
with open(output_path, "wb") as output_file:
shutil.copyfileobj(response.raw, output_file)
With the mastered files downloaded locally, we can listen to both and hear the difference between the original and one of our Masters.
We can also hear the subtle differences between the Masters.
For the purposes of this demo, we only mastered with the last three profiles, however, there are 14 different music mastering profiles to pick from. From my testing, I like the “Classical” profile (Profile n) the best, but everyone is different, try it out yourself.
A More Modern Example
Whilst the classic still doesn’t sound modern, remastering the track does make it a little clearer and hence more enjoyable to listen to. Typically the Dolby.io Music Mastering API is built for contemporary samples recorded on more modern equipment in lossless formats such as FLAC and is not designed to be an audio restoration tool. For the purposes of this investigation, we wanted to see the impact post-production mastering would have on the track rather than attempting to outright “fix” the original.
Currently, the Dolby.io team has a demo hosted here that lets you listen to before and after examples of licensed contemporary tracks which better exemplifies the use case of the API. Because Dolby.io owns the licenses to those songs they are allowed to host the content, whereas for this project I wanted to pick a track in the public domain so anyone with an interest can test it out for themselves without fear of infringing on copyright law.
If the Music Mastering API is something you are interested in further exploring check out the dolby.io documentation around the API or the live demo mentioned above, otherwise let’s get excited for an awesome Baseball season ahead and “root, root, root for the home team”.