Posted inHOWTO

HowTo: Create Spoken Caller ID Ringtones for iPhone via AppleScript

For a long time, I’ve wanted the ability for the iPhone to speak the name of the caller, based on matching the inbound number to the numbers in Contacts. I waited and waited for iPhone OS 2.x ad then 3.x to do this for me, and do it better, but got sick of waiting. So instead, I wrote an AppleScript app I call Contact Caller ID + Sound Ringtone Maker [44KB download;  mirror (v 1.1)]. I’ve used this script to generate over 100 in-use ringtones, and use it to customize a ringtone for a contact or two almost daily now.

This AppleScript will generate a spoken name file, optionally looking for first, last, and nicknames, for selected Address Book Contacts. For example, “Jennifer Frickin’ Connelly is calling….”. It will optionally add a traditional (or other) ringtone of your choice to either the beginning or end of a new spoken-text ringtone file:

“Rob Griffiths is calling… [old phone ring here]; [repeat]”
“[old phone ring here] … Steve Jobs is calling… ; [repeat]”

The script will then add that newly-created file to iTunes, ready for your next sync with iPhone.

You may optionally enter Custom Text (hint: phonetic spelling) when Alex fails to pronounce some of your more exotic friends’ and family’s names. But it is worth easily minutes of giggles to hear what he comes up with on his own.

You can test these custom entries over and over until you are ready to commit to a finished ringtone. You may enter any text you wish spoken, but the longer it is, the bigger the finished ringtone file, and the longer it takes to repeat a loop on your phone. I suggest six to ten seconds, with 30 seconds max. There’s a reason most ringtones are short; don’t try to make ‘In a Gadda Da Vida’ into a ringtone.

On that note, I have not tested this script with overly large add-on ringtones; QuickTime may slow down considerably when trying to export very large files, and may thus produce timing and/or timeout errors. If your files hang, try smaller ones, or add delays after the export command in the script. If you still have problems, try this script with this Old Ring.m4r ringtone.

Make one ringtone first and try it out on your iPhone before you make a bunch. While you can just make them all again (this script is designed to overwrite existing same-name files), you may want to use QuickTime to permanently adjust the volume in your source add-on file to be louder or quieter. There’s nothing to do for the spoken portion of the ringtone without manual manipulation, on a case by case basis in QuickTime. It would require a different routine to combine these automatically, and I don’t really care to implement it.

This script was written and tested for iTunes 8.2 using QuickTime Player Pro 7.6.2 and Quicktime Player (non-Pro) 7.6.2 and Mac OS X 10.5.7 on a Mac Pro Quad 2.8Ghz; no other compatibility testing has been performed, but if you have problems, I will try to help.

I really don’t know if it will work reliably on all file types without QuickTime Pro (or especially with slower hardware). I have only tested this script against AAC, AIFF, SND, MOV, CAF and MPEG files; you may require QuickTime Pro to use other file types. One weird thing is that you cannot export using the File menu in non-Pro QuickTime Player, but you can use AppleScript’s QuickTime library to export anyway. You can switch off the QuickTime check below if it works OK for you as is.

This Script should be installed to ~/Library/Scripts/Applications/Address Book, and run via the Scripts Menu or FastScripts for best performance. Google either for instructions to enable. Alternatively, you may open and run the script via Script Editor (or other AppleScript engine), or use Save As… to save it as an Application and run manually, but it will be slower and dialogs won’t show up where you expect, as I’ve designed it to run in background.

You can also add activate commands to improve performance in QuickTime, if you are willing to leave the keyboard and mouse alone while it’s working. If you screw around, you will likely lose the clipboard. On that note, do not use the clipboard while making large batches of ringtones! This script relies on copy/replace.

You can change the spoken voice with the global useVoice variable at the top of the page.

You can set QuickTime export quality to a higher setting than default 128kbps/Better settings; on my first run I just set it manually once in QuickTime, then used ‘Most Recent Settings’. Later I had it yank a static link to a better profile in my home folder for permanent use when I add a new contact to Address Book and subsequent Ringtone.

It is possible to have System Events or Standard Additions write a temporary QuickTime export profile to disk, then ask QuickTime to use that profile when exporting. I have included the QuickTime settings file for 192kbps in an inactive routine at the end of this file; feel free to get it working as an option, or just use the profile as a static link on disk. Change ExportHigh to true if you want to play with it. Read the AppleScript dictionary for generating and using QuickTime settings profiles. Why Quicktime Player, especially Pro, won’t just let me save and use a profile is beyond me. You could probably add a profile to the plist and get it to show up in QuickTime Pro using defaults write via shell.

Finally, I have not written any significant AppleScripts in five years; there’s some stupid workarounds and improper use of globals, etc.; I also wish I had had time to use script properties. I’d love for someone to clean up and return said clean code. The script is pretty obvious in its variables and uses per naming conventions, but I’ve applied pretty liberal comments for newbies. I have no interest in really improving it myself, as it suits my own limited purposes, but I’d love to relearn where i should have done better. Someone really should wrap this in AppleScript Studio, Smile, or, better, just make it over in Objective C and make it free, of course.

NOTE: make sure you read the entire tutorial, and if you have any problems, make sure you read the comments on macOSXhints