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

6.7 KiB

文本转语音 - 树莓派

在本课的这一部分,你将编写代码,通过语音服务将文本转换为语音。

使用语音服务将文本转换为语音

可以通过 REST API 将文本发送到语音服务,以获取可以在你的 IoT 设备上播放的音频文件。在请求语音时,你需要指定使用的语音,因为语音可以通过多种不同的声音生成。

每种语言都支持一系列不同的声音,你可以通过向语音服务发送 REST 请求来获取每种语言支持的声音列表。

任务 - 获取语音

  1. 在 VS Code 中打开 smart-timer 项目。

  2. say 函数上方添加以下代码,以请求某种语言的声音列表:

    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 上的语言和语音支持文档 获取支持的声音的完整列表。如果你想使用特定的声音,可以删除此函数并将声音名称硬编码为文档中的声音名称。例如:

    voice = 'hi-IN-SwaraNeural'
    

任务 - 将文本转换为语音

  1. 在此代码下方,定义一个常量,用于从语音服务中检索音频格式。当你请求音频时,可以选择多种不同的格式。

    playback_format = 'riff-48khz-16bit-mono-pcm'
    

    你可以使用的格式取决于你的硬件。如果在播放音频时遇到 Invalid sample rate 错误,请将其更改为其他值。你可以在 Microsoft Docs 上的文本转语音 REST API 文档 中找到支持的值列表。你需要使用 riff 格式音频,可以尝试的值包括 riff-16khz-16bit-mono-pcmriff-24khz-16bit-mono-pcmriff-48khz-16bit-mono-pcm

  2. 在此代码下方,声明一个名为 get_speech 的函数,该函数将使用语音服务 REST API 将文本转换为语音:

    def get_speech(text):
    
  3. get_speech 函数中,定义要调用的 URL 和需要传递的请求头:

        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并定义所需的音频格式。

  4. 在此代码下方,定义要发送到 REST API 的 SSML

    ssml =  f'<speak version=\'1.0\' xml:lang=\'{language}\'>'
    ssml += f'<voice xml:lang=\'{language}\' name=\'{voice}\'>'
    ssml += text
    ssml += '</voice>'
    ssml += '</speak>'
    

    此 SSML 设置了要使用的语言和声音,以及要转换的文本。

  5. 最后,在此函数中添加代码以发出 REST 请求并返回二进制音频数据:

    response = requests.post(url, headers=headers, data=ssml.encode('utf-8'))
    return io.BytesIO(response.content)
    

任务 - 播放音频

  1. get_speech 函数下方,定义一个新函数,用于播放 REST API 调用返回的音频:

    def play_speech(speech):
    
  2. 传递给此函数的 speech 是 REST API 返回的二进制音频数据。使用以下代码将其作为波形文件打开,并传递给 PyAudio 以播放音频:

    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 流,与捕获音频的方式相同。不同之处在于,此流设置为输出流,并从音频数据中读取数据并推送到流中。

    流的详细信息(如采样率)不是硬编码的,而是从音频数据中读取的。

  3. say 函数的内容替换为以下代码:

    speech = get_speech(text)
    play_speech(speech)
    

    此代码将文本转换为二进制音频数据,并播放音频。

  4. 运行应用程序,并确保函数应用程序也在运行。设置一些计时器,你会听到语音响应,告诉你计时器已设置,然后在计时器完成时听到另一个语音响应。

    如果遇到 Invalid sample rate 错误,请按照上述说明更改 playback_format

💁 你可以在 code-spoken-response/pi 文件夹中找到此代码。

😀 你的计时器程序运行成功!

免责声明
本文档使用AI翻译服务Co-op Translator进行翻译。尽管我们努力确保准确性,但请注意,自动翻译可能包含错误或不准确之处。应以原始语言的文档作为权威来源。对于关键信息,建议使用专业人工翻译。对于因使用本翻译而引起的任何误解或误读,我们不承担责任。