Skip to content

Instantly share code, notes, and snippets.

@stupidpupil
Created January 10, 2017 22:33
Show Gist options
  • Save stupidpupil/ca5e0efa0537a84f0944d3f2f4068b32 to your computer and use it in GitHub Desktop.
Save stupidpupil/ca5e0efa0537a84f0944d3f2f4068b32 to your computer and use it in GitHub Desktop.
A script for spelling out strings using macOS's `say` command
#!/usr/bin/env ruby
# A script for spelling out strings using macOS's `say` command.
# Uses the NATO/ICAO spelling alphabet, mostly.
# Mapped to spellings that produce the desired effect, specifically with the Fiona voice.
# Didn't use phonemes as these are not reliably available for recent (Nuance) voices.
# TODO: Use ICU to get Unicode character names
mapping = {
'a' => 'alfa',
'å' => 'alfah-alfa',
'ä' => 'alfah-ehcko',
'b' => 'bravo',
'c' => 'charlie',
'd' => 'delta',
'e' => 'echo',
'f' => 'foxtrot',
'g' => 'golf',
'h' => 'ho-tel',
'i' => 'india',
'j' => 'juliet',
'k' => 'kilo',
'l' => 'lemur',
'm' => 'mike',
'n' => 'november',
'o' => 'oscar',
'ö' => 'oscar-ehcko',
'p' => 'papa',
'q' => 'queen',
'r' => 'romeo',
's' => 'sierra',
't' => 'tango',
'u' => 'uniform',
'ü' => 'uniform-ehcko',
'v' => 'victor',
'w' => 'whiskey',
'x' => 'ecks ray',
'y' => 'yankey',
'z' => 'zulu',
'-' => 'dash',
'0' => 'zero',
'1' => 'one',
'2' => 'two',
'3' => 'three',
'4' => 'fower',
'5' => 'fife',
'6' => 'six',
'7' => 'seven',
'8' => 'eight',
'9' => 'niner',
' ' => 'space',
'|' => 'pipe symbol',
'/' => 'forward slash',
'\\' => 'backslash',
'(' => 'left bracket',
')' => 'right bracket',
'[' => 'left square bracket',
']' => 'right square bracket',
'=' => 'equals sign',
'+' => 'plus sign',
'"' => 'double quotation mark',
'`' => 'backtick',
',' => 'com-ah',
'\'' => 'an a postrophy',
';' => 'semi-colon',
':' => 'colon',
'?' => 'question mark',
'^' => 'hat symbol',
'.' => 'full stop',
'%' => 'percent sign',
'&' => 'ampersand',
'>' => 'greater than sign',
'<' => 'less than sign',
'$' => 'dollar sign',
'@' => 'at sign',
'#' => 'hash'
}
#https://unfinishedbitness.info/2015/02/10/taming-talk-on-os-x/
#https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/SpeechSynthesisProgrammingGuide/FineTuning/FineTuning.html
input = ARGF.read.to_s.strip
spelt = []
input.each_char do |chr|
mapped = mapping[chr.downcase]
mapped = "[[char LTRL]] #{chr} [[char NORM]]" if mapped.nil? # This doesn't work terribly well. Has problems with preceding pauses.
mapped = "[[slnc 100]] uppercase #{mapped} [[slnc 50]]," if chr.downcase != chr
spelt << mapped
end
say_string = "[[pmod 10]]\n"
spelt.each_with_index do |s, i|
if i == spelt.count-1
say_string << ", and [[slnc 150]]"
end
say_string << "#{s}"
say_string << "[[slnc 400]] "
if ((i % 3) == 2 and (i != spelt.count-2) and (i != spelt.count-1))
say_string << "[[slnc 800]]\n"
end
end
say_string = "Stand by. [[slnc 2000]] #{say_string} [[slnc 1500]] I say again: [[slnc 800]] #{say_string} [[slnc 400]] Clear"
puts input
exec "say -v Fiona \"#{say_string}\""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment