クイックスピーチの例

クイック・スピーチのサンプルは、ユーザーが提供したテキストを読み上げます。

Quick Speechの例では、TextToSpeech タイプをQt Quickアプリケーションで使用し、テキストを読み上げたり、音声を制御したりする方法を示します。

この例では、Qt Quick Controls を使用して、音声のピッチ、音量、速度を制御します。また、ユーザーがエンジン、言語、音声を選択できるようになっています。

TextToSpeechの初期化

まず、音声合成オブジェクトtts を初期化します:

    TextToSpeech {
        id: tts
        volume: volumeSlider.value
        pitch: pitchSlider.value
        rate: rateSlider.value

ステータスの取得

フッターのLabelstatusLabel

        onStateChanged: updateStateLabel(state)

        function updateStateLabel(state)
        {
            switch (state) {
                case TextToSpeech.Ready:
                    statusLabel.text = qsTr("Ready")
                    break
                case TextToSpeech.Speaking:
                    statusLabel.text = qsTr("Speaking")
                    break
                case TextToSpeech.Paused:
                    statusLabel.text = qsTr("Paused...")
                    break
                case TextToSpeech.Error:
                    statusLabel.text = qsTr("Error!")
                    break
            }

音声に合わせて単語をハイライトする

TextArea input は、入力するテキストと、トリガーとしてのonSayingWord シグナルを取得するために使用され、また、発話された単語をハイライトする位置を知るためにも使用されます。

        onSayingWord: (word, id, start, length)=> {
            input.select(start, start + length)

TextArea input はここで宣言される:

    ColumnLayout {
        anchors.fill: parent
        anchors.margins: 8
        id: inputForm

        TextArea {
            id: input
            wrapMode: TextEdit.WordWrap
            text: qsTr("Hello, world!")
            Layout.fillWidth: true
            Layout.minimumHeight: implicitHeight
            font.pointSize: 24
        }

音声の制御

Button タイプは で配置され、 を制御するように設定されています。RowLayout TextToSpeech tts

発話ボタン

Speak」というラベルのButton が作成される。このボタンは、tts の state プロパティがPaused またはReady の場合に有効になります。

        RowLayout {
            Button {
                text: qsTr("Speak")
                enabled: [TextToSpeech.Paused, TextToSpeech.Ready].includes(tts.state)

ボタンがクリックされると、ターゲット・デバイスで利用可能なボイスが検索され、tts.voice が現在選択されているボイスvoicesComboBox に設定される。次にTextToSpeech::say() が呼び出され、inputbox のテキストが渡される。

                onClicked: {
//! [say0]
                    let voices = tts.availableVoices()
                    tts.voice = voices[voicesComboBox.currentIndex]
//! [say1]
                    tts.say(input.text)
                }

一時停止、再開、停止ボタン

これらのボタンは、Speak ボタンと実装が似ています:

            Button {
                text: qsTr("Pause")
                enabled: tts.state == TextToSpeech.Speaking
                onClicked: tts.pause()
                visible: tts.engineCapabilities & TextToSpeech.Capabilities.PauseResume
            }
//! [pause]
//! [resume]
            Button {
                text: qsTr("Resume")
                enabled: tts.state == TextToSpeech.Paused
                onClicked: tts.resume()
                visible: tts.engineCapabilities & TextToSpeech.Capabilities.PauseResume
            }
//! [resume]
            Button {
                text: qsTr("Stop")
                enabled: [TextToSpeech.Speaking, TextToSpeech.Paused].includes(tts.state)
                onClicked: tts.stop()
            }
        }

テキスト読み上げオプションの選択

GridLayout 、音声合成のエンジン、ロケール、音声、音量、ピッチ、レートの各オプションを選択するためのコントロールとラベルが配置されています。

エンジン、ロケール、音声の選択

これらのパラメータの選択にはComboBox コンポーネントのグループを使用します。

エンジンの選択にはComboBox,tts.availableEngines() がモデルとして使われます。

onActivated は、コンボボックスの現在のインデックスにある現在のテキストをtts.engineに割り当てるトリガーです。

            Text {
                text: qsTr("Engine:")
            }
            ComboBox {
                id: enginesComboBox
                Layout.fillWidth: true
                model: tts.availableEngines()
                onActivated: {
                    tts.engine = textAt(currentIndex)
                    updateLocales()
                    updateVoices()

上記のコードスニペットの最後の2行は、選択されたエンジンに依存するため、利用可能なロケールとボイスがこの時点で更新されることを示しています。これらの関数については、次のセクションで説明します。

localesComboBoxengineComboBox と同じように実装されていますが、利用可能なエンジンは更新されません。

                }
            }
            Text {
                text: qsTr("Locale:")
            }
            ComboBox {
                id: localesComboBox
                Layout.fillWidth: true
                onActivated: {
                    let locales = tts.availableLocales()
                    tts.locale = locales[currentIndex]
                    updateVoices()
                }
            }
            Text {
                text: qsTr("Voice:")
            }
            ComboBox {
                id: voicesComboBox
                Layout.fillWidth: true
            }
ボリューム、ピッチ、レートの選択

これらのコントロールはSliders で以下のように実装されている:

            Text {
                text: qsTr("Volume:")
            }
            Slider {
                id: volumeSlider
                from: 0
                to: 1.0
                stepSize: 0.2
                value: 0.8
                Layout.fillWidth: true
            }
            Text {
                text: qsTr("Pitch:")
            }
            Slider {
                id: pitchSlider
                from: -1.0
                to: 1.0
                stepSize: 0.5
                value: 0
                Layout.fillWidth: true
            }
            Text {
                text: qsTr("Rate:")
            }
            Slider {
                id: rateSlider
                from: -1.0
                to: 1.0
                stepSize: 0.5
                value: 0
                Layout.fillWidth: true
            }
        }
    }

利用可能なオプションの更新

Component.onCompleted シグナルを使用して、ルートApplicationWindow がインスタンス化されると、以下のことが行われる。

  • enginesComboBox インデックスは、現在設定されているtts のエンジンに設定されます。
  • 利用可能なロケールとボイスが更新される。
  • tts の現在の状態がシグナルされます。
    Component.onCompleted: {
        enginesComboBox.currentIndex = tts.availableEngines().indexOf(tts.engine)
        // some engines initialize asynchronously
        if (tts.state == TextToSpeech.Ready) {
            engineReady()

アプリケーション全体で使用されるupdateLocales()updateVoice() 関数は、以下のように実装されています:

        } else {
            tts.stateChanged.connect(root.engineReady)
        }

        tts.updateStateLabel(tts.state)
    }

    function engineReady() {
        tts.stateChanged.disconnect(root.engineReady)
        if (tts.state != TextToSpeech.Ready) {
            tts.updateStateLabel(tts.state)
            return;
        }
        updateLocales()
        updateVoices()
    }

    function updateLocales() {
        let allLocales = tts.availableLocales().map((locale) => locale.nativeLanguageName)
        let currentLocaleIndex = allLocales.indexOf(tts.locale.nativeLanguageName)
        localesComboBox.model = allLocales
        localesComboBox.currentIndex = currentLocaleIndex
    }

    function updateVoices() {
        voicesComboBox.model = tts.availableVoices().map((voice) => voice.name)
        let indexOfVoice = tts.availableVoices().indexOf(tts.voice)
        voicesComboBox.currentIndex = indexOfVoice

例の実行

Qt Creator からサンプルを実行するには、Welcome モードを開き、Examples からサンプルを選択します。詳細については、Building and Running an Example を参照してください。

サンプルプロジェクト @ code.qt.io

©2024 The Qt Company Ltd. 本書に含まれるドキュメントの著作権は、それぞれの所有者に帰属します。 ここで提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。