In a previous tutorial, Give Your Mac a Voice with Text-to-Speech, I showed you how to use the speech function of your Mac. One particular section of that that guide detailed the process of creating a spoken-word ringtone by using the Mac's
say command and the Mac app Ringer.
In this tutorial, I'll show you how you can automate this process by creating a plug-in for Contacts using Automator. This plug-in will automatically generate a spoken-word ringtone for us to use without needing to endlessly type anything into Terminal.
Before We Begin
In order to get the most from our ringtones, you'll need the Mac app Ringer ($3.99 from the Mac App Store). I'll explain why this app is required a little later on.
Our Service for Contacts will work as follows:
- Select a contact name we'd like to create a ringtone for.
- Highlight the text of the name, nickname or company of the contact.
- Right-click on the selected text and, upon selecting our Service, a new ringtone will automatically be generated and sent to Ringer to add any gaps or fades.
- The ringtone can then be sent to iTunes.
I'm going to use a combination of Automator and a shell script to fulfil our requirements. Automator is an extremely powerful automation tool that allows almost anyone to create extremely powerful scripts with little to no experience of scripting.
Automator workflows work by taking an input, whether this is a file or text selection, and then performs an action upon it.
Open Automator, located in your Applications folder and select Service as the document type.
Once a new document has loaded, you'll see that our service is expecting to receive selected text in any application. Leave the first option as it is but change any application to Contacts.
In the Actions list, search for shell and you'll see an action called Run Shell Script. Drag it over to the main workflow area.
You need to make a slight change so that we can use the text we've selected as part of the script, known as a variable.
Change the option for Pass Input from to stdin to as arguments. The contents of the action will then change and appear as below.
2. The Shell Script
To make things easier, I've included the script that you need to enter below. It's everything you need within the action so you can clear the action completely and replace it with the text below.
for f in "$@" do # Step 1: Specify a temporary location and filename to save our ringtone to loc=~/Desktop filename=temp.aiff # Step 2: Use the 'say' command to generate our ringtone say -o $loc/$filename "$1 is calling" # Step 3: Now we've created a temporary ringtone, let's rename it mv $loc/$filename "$loc/$1.aiff" # Step 4: Finally, let's open this in Ringer to make any final adjustments open -a /Applications/Ringer.app "$loc/$1.aiff" done
Let's break this script down and explore what it does first.
# Step 1: Specify a temporary location and filename to save our ringtone to loc=~/Desktop filename=temp.aiff
This deals with setting some temporary information. In the script above, we specify a temporary name and location for our ringtone file and assign them as a variable. Shell script variables will start with a dollar sign when we want to use them.
Here, our ringtone will start off being called temp.aiff (which will be referred to as
$filename) and will be saved to your Desktop (referred to as
# Step 2: Use the 'say' command to generate our ringtone say -o $loc/$filename "$1 is calling"
Here, we use the
say command to say our highlighted contact's name and save it into an audio file. We use
$1 to represent the input that Automator has given us. Our service uses the text we will have selected as the input, passing it on to our shell script, represented by
$1. Just like our temporary filename, our variable here starts off with a dollar sign.
Our ringtone will say "Contact name is calling". If you did this for Johnny Appleseed, the ringtone would say "Johnny Appleseed is calling".
# Step 3: Now we've created a temporary ringtone, let's rename it mv $loc/$filename "$loc/$1.aiff"
This step renames the temporary file to the name of our contact. For example, if I generated a ringtone for "Johnny Appleseed", it would start out as temp.aiff and then be renamed to Johnny Appleseed.aiff. Although the
say command creates the file and names it, it doesn't deal well with any special characters or spaces within the filename. We require this additional step so we can name our new file after our contact.
# Step 4: Finally, let's open this in Ringer to make any final adjustments open -a /Applications/Ringer.app "$loc/$1.aiff"
Finally, the newly-created ringtone is opened in the app Ringer, allowing us to make some additional changes.
3. Generate a Ringtone
Once you have copied and pasted the script above into the Automator's Run Shell Script action, it's time to save. Save the file with the name Generate Ringtone… and then open Contacts.
Select a contact and highlight either the name, nickname or company name. Right-click and then select Generate Ringtone… which will be under the Services menu. As soon as you select it, a new ringtone will be instantly created on your desktop that has the name of the contact as the file name. A few moments later, Ringer will launch with the ringtone loaded and ready to make any changes to.
say command can actually generate ringtone files that are compatible with an iPhone without any additional software. If we were to alter the script so that it generates a .m4r file instead of .aiff then we could bypass using the app completely and place it into iTunes.
But there's a problem with that. Ringtones on the iPhone loop. Unless we use an app like Ringer to add a gap to our ringtone then it would get incredibly annoying to hear "Johnny Appleseed is ringing, Johnny Appleseed is ringing, Johnny Appleseed is ringing" without any gap. It would certainly sound like Siri is being excessively impatient with us!
Now that our ringtone is within Ringer, make sure to add a gap of at least three seconds to the end of the file. That way, there's a nice gap before the ringtone loops.
You can then send your ringtone to iTunes which will still have the contact name as the ringtone. All you need to do then is assign it as a ringtone.
Although not entirely autonomous, you can create a number of different ringtones for different contacts quickly and easily. What's more, since the service we've created takes any form of selected text from Contacts, you can generate a ringtone using a nickname or business name.
As part of this tutorial, I've included a ready-made Automator workflow for you to use. Simply open the file and you can select whether to edit the workflow in Automator or install it as a Service.