speech
speech 模块让 micro:bit 说话、唱歌并发出其他类语音声音。默认情况下,声音会通过边缘连接器上的引脚 0 以及板载扬声器输出。你可以将有线耳机或扬声器连接到边缘连接器的引脚 0 与 GND 来收听声音。

使用前需先导入:
import speech
下文示例均假设已完成导入。
函数
translate(words)
给定字符串 words 中的英文单词,返回包含适当音素(用于发音)的最佳猜测字符串。
此函数用于生成音素的初步近似,可进一步手工编辑以提高准确性、语调和重音。
pronounce(phonemes, *, pitch=64, speed=72, mouth=128, throat=128)
pronounce(phonemes, *, pitch=64, speed=72, mouth=128, throat=128, pin=pin0)
发音字符串 phonemes 中的音素。详见下文音素用法,以精细控制语音合成器输出。可覆盖可选参数 pitch、speed、mouth、throat 以改变音色(音质)。
可选参数 pin 可指定输出引脚,覆盖默认的 pin0。若不想从引脚输出声音,可使用 pin=None。
say(words, *, pitch=64, speed=72, mouth=128, throat=128)
say(words, *, pitch=64, speed=72, mouth=128, throat=128, pin=pin0)
说出字符串 words 中的英文单词。对英语效果尚可。可覆盖可选参数以改变音色。这是 speech.pronounce(speech.translate(words)) 的简写。
sing(phonemes, *, pitch=64, speed=72, mouth=128, throat=128)
sing(phonemes, *, pitch=64, speed=72, mouth=128, throat=128, pin=pin0)
演唱字符串 phonemes 中的音素。改变音高与音符时长见下文。可覆盖可选参数以改变音色。
标点
标点用于改变语音表达方式。合成器理解四种标点:连字符、逗号、句号和问号。
连字符(-)标记从句边界,插入短停顿。
逗号(,)标记短语边界,插入约为连字符两倍的停顿。
句号(.)和问号(?)结束句子。
句号插入停顿并使音高下降。
问号也插入停顿但使音高上升。这对「are we home yet?」这类是非问句效果较好,对「why are we going home?」这类复杂问句效果较差——后者宜用句号。
音色
声音的音色即音质——例如 DALEK 与人类声音的差异。要控制音色,可调整 pitch、speed、mouth 和 throat 参数的数值。
音高(声音高低)和语速(说话快慢)较直观,一般分类如下:
Pitch(音高):
- 0–20 不实用
- 20–30 很高
- 30–40 高
- 40–50 偏高正常
- 50–70 正常
- 70–80 偏低正常
- 80–90 低
- 90–255 很低
(默认 64)
Speed(语速):
- 0–20 不实用
- 20–40 很快
- 40–60 快
- 60–70 快对话
- 70–75 正常对话
- 75–90 叙述
- 90–100 慢
- 100–225 很慢
(默认 72)
mouth 与 throat 较难用文字说明,以下描述基于我们改变各设置时听到的印象。
mouth 数值越低,越像说话时不动嘴唇;数值越高(最高 255),越像夸张口型。
throat 数值越低,说话越放松;数值越高,语调越紧张。
关键是实验并调整,直到得到你想要的效果。
入门示例:
speech.say("I am a little robot", speed=92, pitch=60, throat=190, mouth=190)
speech.say("I am an elf", speed=72, pitch=64, throat=110, mouth=160)
speech.say("I am a news presenter", speed=82, pitch=72, throat=110, mouth=105)
speech.say("I am an old lady", speed=82, pitch=32, throat=145, mouth=145)
speech.say("I am E.T.", speed=100, pitch=64, throat=150, mouth=200)
speech.say("I am a DALEK - EXTERMINATE", speed=120, pitch=100, throat=100, mouth=200)
音素
say 函数便于产生语音,但往往不够准确。要确保合成器完全按你的期望发音,需使用音素:区分不同单词的最小可感知声音单位,即语音的基本构成块。
pronounce 函数接受包含简化可读版国际音标的字符串,以及可选标注以表示语调与重音。
使用音素的优势是你不必会拼写——只需知道怎么说,就能按语音拼写。
下表列出合成器理解的音素。
简单元音 浊辅音
IY f(ee)t R (r)ed
IH p(i)n L a(ll)ow
EH b(e)g W a(w)ay
AE S(a)m W (wh)ale
AA p(o)t Y (y)ou
AH b(u)dget M Sa(m)
AO t(al)k N ma(n)
OH c(o)ne NX so(ng)
UH b(oo)k B (b)ad
UX l(oo)t D (d)og
ER b(ir)d G a(g)ain
AX gall(o)n J (j)u(dg)e
IX dig(i)t Z (z)oo
ZH plea(s)ure
双元音 V se(v)en
EY m(a)de DH (th)en
AY h(igh)
OY b(oy)
AW h(ow) 清辅音
OW sl(ow) S (S)am
UW cr(ew) SH fi(sh)
F (f)ish
TH (th)in
特殊音素 P (p)oke
UL sett(le) (=AXL) T (t)alk
UM astron(om)y (=AXM) K (c)ake
UN functi(on) (=AXN) CH spee(ch)
Q kitt-en (声门塞音) /H a(h)ead
以下非标准符号也可使用:
YX 双元音结尾(Y 的弱版)
WX 双元音结尾(W 的弱版)
RX 元音后的 R(R 的平滑版)
LX 元音后的 L(L 的平滑版)
/X 非前元音或辅音前的 H — 如 (wh)o
DX 如 pi(t)y 中的 T(T 的弱版)
较少使用的音素组合(及建议替代):
音素组合 你可能想要: 除非音节分割如:
GS GZ 如 ba(gs) bu(gs)pray
BS BZ 如 slo(bz) o(bsc)ene
DS DZ 如 su(ds) Hu(ds)son
PZ PS 如 sla(ps) -----
TZ TS 如 cur(ts)y -----
KZ KS 如 fi(x) -----
NG NXG 如 singing i(ng)rate
NK NXK 如 bank Su(nk)ist
若使用上述以外的音素,将引发 ValueError 异常。音素以字符串传入:
speech.pronounce("/HEHLOW") # "Hello"
音素分为元音与辅音两大类。元音又分为简单元音与双元音——简单元音发音不变,双元音从一个音过渡到另一个。例如说「oil」时,「oi」从「oh」过渡到「ee」。
辅音也分浊辅音与清辅音。浊辅音需声带振动,如 L、N、Z;清辅音靠气流,如 P、T、SH。
熟悉后音素系统很简单。起初某些拼写可能棘手(如「adventure」含「CH」),规则是写你怎么说,不是怎么拼。实验是解决难词的最好办法。
为使语音自然易懂,常用内置重音系统添加语调或强调。
有八个重音标记,用数字 1–8 表示。在要重读的元音后插入相应数字。例如「/HEHLOW」缺乏表情,改为「/HEH3LOW」会更友好。
重音也可改变词义。考虑「Why should I walk to the store?」,可有多种读法:
# 你需要一个理由
speech.pronounce("WAY2 SHUH7D AY WAO5K TUX DHAH STOH5R.")
# 你不太愿意去
speech.pronounce("WAY7 SHUH2D AY WAO7K TUX DHAH STOH5R.")
# 你想让别人去
speech.pronounce("WAY5 SHUH7D AY2 WAO7K TUX DHAH STOHR.")
# 你更想开车
speech.pronounce("WAY5 SHUHD AY7 WAO2K TUX7 DHAH STOHR.")
# 你想去别处
speech.pronounce("WAY5 SHUHD AY WAO5K TUX DHAH STOH2OH7R.")
不同重音产生更有表现力的语调。它们通过提高或降低音高、延长对应元音实现,数字越小强调越强烈。重音标记也有助于正确发音难词——若某音节不够清晰,可加入中性重音标记。
也可通过重音标记延长发音:
speech.pronounce("/HEH5EH4EH3EH2EH2EH3EH4EH5EHLP.")
演唱
可以让 BiBoPython 演唱音素。
做法是在音素前标注与音高相关的数字——数字越小音越高。数字大致对应下图音符:
要标注音高,在音素前加井号 # 和音高数字。音高保持到出现新标注。例如唱音阶:
solfa = [
"#115DOWWWWWW", # Doh
"#103REYYYYYY", # Re
"#94MIYYYYYY", # Mi
"#88FAOAOAOAOR", # Fa
"#78SOHWWWWW", # Soh
"#70LAOAOAOAOR", # La
"#62TIYYYYYY", # Ti
"#58DOWWWWWW", # Doh
]
song = ''.join(solfa)
speech.sing(song, speed=100)
要让音符持续一定时长,可重复元音或浊辅音音素(见上例)。注意双元音——要延长需拆成组成部分,例如「OY」可延长为「OHOHIYIYIY」。
实验、仔细听并调整,是确定重复次数以达到所需时长的唯一可靠方法。
工作原理
原始手册解释得很清楚:
首先,我们不录制实际语音波形,只存储频率频谱。这样既省内存又有其他优势。其次,我们存储一些关于时序的数据——各音素在不同情况下的持续时间,以及过渡时间以便与相邻音素混合。第三,我们设计规则系统处理这些数据——很快我们的计算机就开始咿呀学语了。
—— S.A.M. 用户手册。
输出经 audio 模块提供的函数处理,于是 micro:bit 就能说话了。