You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
IoT-For-Beginners/translations/zh/6-consumer/lessons/3-spoken-feedback/pi-text-to-speech.md

154 lines
6.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "606f3af1c78e3741e48ce77c31cea626",
"translation_date": "2025-08-25T00:10:24+00:00",
"source_file": "6-consumer/lessons/3-spoken-feedback/pi-text-to-speech.md",
"language_code": "zh"
}
-->
# 文本转语音 - 树莓派
在本课的这一部分,你将编写代码,通过语音服务将文本转换为语音。
## 使用语音服务将文本转换为语音
可以通过 REST API 将文本发送到语音服务,以获取可以在你的 IoT 设备上播放的音频文件。在请求语音时,你需要指定使用的语音,因为语音可以通过多种不同的声音生成。
每种语言都支持一系列不同的声音,你可以通过向语音服务发送 REST 请求来获取每种语言支持的声音列表。
### 任务 - 获取语音
1. 在 VS Code 中打开 `smart-timer` 项目。
1.`say` 函数上方添加以下代码,以请求某种语言的声音列表:
```python
def get_voice():
url = f'https://{location}.tts.speech.microsoft.com/cognitiveservices/voices/list'
headers = {
'Authorization': 'Bearer ' + get_access_token()
}
response = requests.get(url, headers=headers)
voices_json = json.loads(response.text)
first_voice = next(x for x in voices_json if x['Locale'].lower() == language.lower() and x['VoiceType'] == 'Neural')
return first_voice['ShortName']
voice = get_voice()
print(f'Using voice {voice}')
```
此代码定义了一个名为 `get_voice` 的函数,该函数使用语音服务获取声音列表。然后,它找到与正在使用的语言匹配的第一个声音。
该函数随后被调用以存储第一个声音,并将声音名称打印到控制台。此声音可以请求一次,并在每次调用文本转语音时使用该值。
> 💁 你可以从 [Microsoft Docs 上的语言和语音支持文档](https://docs.microsoft.com/azure/cognitive-services/speech-service/language-support?WT.mc_id=academic-17441-jabenn#text-to-speech) 获取支持的声音的完整列表。如果你想使用特定的声音,可以删除此函数并将声音名称硬编码为文档中的声音名称。例如:
>
> ```python
> voice = 'hi-IN-SwaraNeural'
> ```
### 任务 - 将文本转换为语音
1. 在此代码下方,定义一个常量,用于从语音服务中检索音频格式。当你请求音频时,可以选择多种不同的格式。
```python
playback_format = 'riff-48khz-16bit-mono-pcm'
```
你可以使用的格式取决于你的硬件。如果在播放音频时遇到 `Invalid sample rate` 错误,请将其更改为其他值。你可以在 [Microsoft Docs 上的文本转语音 REST API 文档](https://docs.microsoft.com/azure/cognitive-services/speech-service/rest-text-to-speech?WT.mc_id=academic-17441-jabenn#audio-outputs) 中找到支持的值列表。你需要使用 `riff` 格式音频,可以尝试的值包括 `riff-16khz-16bit-mono-pcm`、`riff-24khz-16bit-mono-pcm` 和 `riff-48khz-16bit-mono-pcm`
1. 在此代码下方,声明一个名为 `get_speech` 的函数,该函数将使用语音服务 REST API 将文本转换为语音:
```python
def get_speech(text):
```
1.`get_speech` 函数中,定义要调用的 URL 和需要传递的请求头:
```python
url = f'https://{location}.tts.speech.microsoft.com/cognitiveservices/v1'
headers = {
'Authorization': 'Bearer ' + get_access_token(),
'Content-Type': 'application/ssml+xml',
'X-Microsoft-OutputFormat': playback_format
}
```
这设置了请求头以使用生成的访问令牌,将内容设置为 SSML并定义所需的音频格式。
1. 在此代码下方,定义要发送到 REST API 的 SSML
```python
ssml = f'<speak version=\'1.0\' xml:lang=\'{language}\'>'
ssml += f'<voice xml:lang=\'{language}\' name=\'{voice}\'>'
ssml += text
ssml += '</voice>'
ssml += '</speak>'
```
此 SSML 设置了要使用的语言和声音,以及要转换的文本。
1. 最后,在此函数中添加代码以发出 REST 请求并返回二进制音频数据:
```python
response = requests.post(url, headers=headers, data=ssml.encode('utf-8'))
return io.BytesIO(response.content)
```
### 任务 - 播放音频
1.`get_speech` 函数下方,定义一个新函数,用于播放 REST API 调用返回的音频:
```python
def play_speech(speech):
```
1. 传递给此函数的 `speech` 是 REST API 返回的二进制音频数据。使用以下代码将其作为波形文件打开,并传递给 PyAudio 以播放音频:
```python
def play_speech(speech):
with wave.open(speech, 'rb') as wave_file:
stream = audio.open(format=audio.get_format_from_width(wave_file.getsampwidth()),
channels=wave_file.getnchannels(),
rate=wave_file.getframerate(),
output_device_index=speaker_card_number,
output=True)
data = wave_file.readframes(4096)
while len(data) > 0:
stream.write(data)
data = wave_file.readframes(4096)
stream.stop_stream()
stream.close()
```
此代码使用 PyAudio 流,与捕获音频的方式相同。不同之处在于,此流设置为输出流,并从音频数据中读取数据并推送到流中。
流的详细信息(如采样率)不是硬编码的,而是从音频数据中读取的。
1.`say` 函数的内容替换为以下代码:
```python
speech = get_speech(text)
play_speech(speech)
```
此代码将文本转换为二进制音频数据,并播放音频。
1. 运行应用程序,并确保函数应用程序也在运行。设置一些计时器,你会听到语音响应,告诉你计时器已设置,然后在计时器完成时听到另一个语音响应。
如果遇到 `Invalid sample rate` 错误,请按照上述说明更改 `playback_format`
> 💁 你可以在 [code-spoken-response/pi](../../../../../6-consumer/lessons/3-spoken-feedback/code-spoken-response/pi) 文件夹中找到此代码。
😀 你的计时器程序运行成功!
**免责声明**
本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保准确性,但请注意,自动翻译可能包含错误或不准确之处。应以原始语言的文档作为权威来源。对于关键信息,建议使用专业人工翻译。对于因使用本翻译而引起的任何误解或误读,我们不承担责任。