Module outloud
[hide private]
[frames] | no frames]

Source Code for Module outloud

  1  """Outloud voice definitions using ACSS. 
  2   
  3  This module encapsulates Outloud-specific voice definitions.  It 
  4  maps device-independent ACSS voice definitions into appropriate 
  5  Outloud voice parameter settings. 
  6   
  7  """ 
  8   
  9  __id__ = "$Id: outloud.py 3535 2005-11-17 14:32:59Z raman $" 
 10  __author__ = "$Author: raman $" 
 11  __version__ = "$Revision: 3535 $" 
 12  __date__ = "$Date: 2005-11-17 06:32:59 -0800 (Thu, 17 Nov 2005) $" 
 13  __copyright__ = "Copyright (c) 2005 T. V. Raman" 
 14  __license__ = "LGPL" 
 15   
 16  _defined_voices = {} 
 17   
 18  # Map from ACSS dimensions to Outloud settings: 
19 -def _update_map(table, key, format, settings):
20 """Internal function to update acss->synth mapping.""" 21 table[key] ={} 22 for setting in settings: 23 _table[key][setting[0]] = format % setting[1:]
24 25 26 _table ={} 27 #family codes: 28 29 _table['family'] = { 30 'paul' : " `v1 ", 31 'male' : " `v1 ", 32 'harry' : " `v1 `vh65 `vb50 ", 33 'man' : " `v1 `vh65 `vb50 ", 34 'dennis' : " `v1 `vb0 ", 35 'frank' : " `v1 `vr100 ", 36 'betty' : " `v7 ", 37 'female' : " `v7 ", 38 'ursula' : " `v2 ", 39 'rita' : " `v2 `vr100 ", 40 'wendy' : " `v2 `vy50 ", 41 'kit' : " `v3 ", 42 'child' : " `v3 " 43 } 44 # Average pitch for standard male voice is 65 --this is mapped to 45 # a setting of 5. 46 # Average pitch varies inversely with speaker head size --a child 47 # has a small head and a higher pitched voice. 48 # We change parameter head-size in conjunction with average pitch to 49 # produce a more natural change on the TTS engine. 50 51 #male average pitch 52 53 _male_ap = [ 54 (0, 0, 90), 55 (1, 13, 81, ), 56 (2, 26, 72), 57 (3, 39, 63), 58 (4, 52, 54, ), 59 (5, 65, 50), 60 (6, 74, 40), 61 (7, 83, 30, ), 62 (8, 87, 26), 63 (9, 92, 21) 64 ] 65 66 _update_map(_table, ('male', 'average-pitch'), 67 " `vb%s `vh%s ", _male_ap) 68 69 #Harry has a big head --and a lower pitch for the middle setting 70 _man_ap = [ 71 (0, 0, 90), 72 (1, 10, 85, ), 73 (2, 20, 80), 74 (3, 30, 70), 75 (4, 40, 60), 76 (5, 50, 60), 77 (6, 60, 50), 78 (7, 70, 40, ), 79 (8, 80, 30), 80 (9, 90, 20) 81 ] 82 83 _update_map(_table,('man', 'average-pitch'), 84 " `vb%s `vh% s",_man_ap) 85 #defalt baseline is average pitch of 81 86 87 _female_ap = [ 88 (0, 5, 70), 89 (1, 17, 66), 90 (2, 33, 62), 91 (3, 49, 58), 92 (4, 65, 54, ), 93 (5, 81, 50), 94 (6, 85, 55), 95 (7, 89, 60), 96 (8, 93, 65), 97 (9, 97, 69) 98 ] 99 100 _update_map(_table, ('female', 'average-pitch'), 101 " `vb%s `vh% s",_female_ap) 102 103 # pitch-range for male: 104 105 106 # Standard pitch range is 30 and is mapped to 107 # a setting of 5. 108 # A value of 0 produces a flat monotone voice --maximum value of 100 109 # produces a highly animated voice. 110 111 112 _male_pr = [ 113 (0,0), 114 (1,5), 115 (2,15), 116 (3,20), 117 (4,25), 118 (5,30), 119 (6,47), 120 (7,64), 121 (8,81), 122 (9,100) 123 ] 124 125 _update_map(_table, ('male', 'pitch-range'), 126 " `vf%s ", _male_pr) 127 128 _man_pr = [ 129 (0, 0, ), 130 (1, 5, ), 131 (2, 15), 132 (3, 20), 133 (4, 25, ), 134 (5, 30, ), 135 (6, 47), 136 (7, 64), 137 (8, 81), 138 (9, 100) 139 ] 140 141 _update_map(_table, ('man', 'pitch-range'), 142 " `vf%s ", _man_pr) 143 144 _female_pr = [ 145 (0, 0, ), 146 (1, 5, ), 147 (2, 15), 148 (3, 20), 149 (4, 25, ), 150 (5, 30, ), 151 (6, 47), 152 (7, 64), 153 (8, 81), 154 (9, 100) 155 ] 156 157 _update_map(_table, ('female', 'pitch-range'), 158 " `vf%s ", _female_pr) 159 160 # Stress: 161 # On the outloud we map stress to roughness 162 163 _male_stress =[ 164 (0, 0), 165 (1, 5), 166 (2, 10), 167 (3, 15), 168 (4, 20, ), 169 (5, 25, ), 170 (6, 30), 171 (7, 35), 172 (8, 40), 173 (9, 45) 174 ] 175 176 _update_map(_table, ('male', 'stress'), 177 " `vr%s ", _male_stress) 178 179 #Same stress values work for female and man: 180 181 _update_map(_table, ('man', 'stress'), 182 " `vr%s ", _male_stress) 183 184 _update_map(_table, ('female', 'stress'), 185 " `vr%s ", _male_stress) 186 187 #richness 188 189 # Smoothness and richness vary inversely. 190 # a maximally smooth voice produces a quieter effect 191 # a rich voice is "bright" in contrast. 192 193 194 _male_richness = [ 195 (0, 0, 60), 196 (1, 4, 78), 197 (2, 8, 80), 198 (3, 12, 84), 199 (4, 16, 88), 200 (5, 20, 92), 201 (6, 24, 93), 202 (7, 28, 95), 203 (8, 32, 97, ), 204 (9, 36, 100) 205 ] 206 207 _update_map(_table, ('male', 'richness'), 208 " `vy%s `vv%s " ,_male_richness) 209 210 #same settings work for man and female: 211 212 _update_map(_table, ('man', 'richness'), 213 " `vy%s `vv%s " , _male_richness) 214 215 _update_map(_table, ('female', 'richness'), 216 " `vy%s `vv%s ", _male_richness) 217 218 # getrate is here for symmetry with other engines: 219 # In the case of outloud, we dont need to normalize 220
221 -def getrate(r): return r
222
223 -def getvoicelist(): return _table['family'].keys()
224
225 -def getvoice(acss):
226 """Memoized function that returns synthesizer code for 227 specified ACSS setting. 228 Synthesizer code is a tupple of the form (open,close) 229 where open sets the voice, and close resets it.""" 230 231 name=acss.name() 232 if name in _defined_voices: return _defined_voices[name] 233 _defined_voices[name] =acss2voice(acss) 234 return _defined_voices[name]
235
236 -def acss2voice(acss):
237 """Return synthesizer code.""" 238 code = "" 239 family ='male' 240 if 'family'in acss: 241 family = acss['family'] 242 code += _table['family'][family] 243 if 'rate' in acss: code += " `vs%s" % acss['rate'] 244 voice = "" 245 for d in ['average-pitch', 'pitch-range', 246 'richness', 'stress']: 247 if d in acss:voice += _table[(family, d)][acss[d]] 248 if code or voice: code = "%s %s" % (code, voice) 249 return (code, " `v1 ")
250