Изменение уровня AVSpeechUtterance в реальном времени

В настоящее время я разрабатываю приложение для iOS, которое преобразует текст в речь с помощью AVSynthesizer.

Что я хочу сделать, так это то, что во время разговора синтезатора может быть изменена частота высказываний с помощью ползунка и скорость речи.

Я делаю это в IBAction ползунка: self.utterance = sender.value

но синтезатор не меняет скорость. Я искал информацию, но еще ничего не нашел. Какой канд я делаю? Заранее спасибо.

2 ответа

Решение

Итак, немного поиграв с этой классной функцией, о которой я не знал, я нашел способ изменить частоту высказываний. Основная проблема заключается в том, что высказывание в настоящее время ставится в очередь синтезатором, rate не может быть изменено Соответствует документации:

/* Setting these values after a speech utterance has been enqueued will have no effect. */

open var rate: Float // Values are pinned between AVSpeechUtteranceMinimumSpeechRate and AVSpeechUtteranceMaximumSpeechRate.

open var pitchMultiplier: Float // [0.5 - 2] Default = 1

open var volume: Float // [0-1] Default = 1

Таким образом, обходной путь должен был бы остановить синтезатор и подать ему новое высказывание с урезанной последовательностью.

class ViewController: UIViewController {
    var synthesizer: AVSpeechSynthesizer!
    var string: String!
    var currentRange: NSRange = NSRange(location: 0, length: 0)

    @IBAction func sl(_ sender: UISlider) {
        synthesizer.stopSpeaking(at: .immediate)

        if currentRange.length > 0 {
            let startIndex = string.index(string.startIndex, offsetBy: NSMaxRange(currentRange))
            let newString = string.substring(from: startIndex)
            string = newString
            synthesizer.speak(buildUtterance(for: sender.value, with: string))
        }
    }

    func buildUtterance(for rate: Float, with str: String) -> AVSpeechUtterance {
        let utterance = AVSpeechUtterance(string: str)
        utterance.rate = rate
        utterance.voice = AVSpeechSynthesisVoice(language: "en-US")
        return utterance
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        string = "I am currently developing an iOS app that converts text to speech using AVSynthesizer.What I want to do is that while the synthesizer is speaking, utterance rate can be changed and with a slider and the speed of the speaking changes. I am doing this in the IBAction of the slider: self.utterance = sender.value but the synthesizer doesnt change the speed. Ive been looking for information but I havent found something yet. What cand I do? Thanks in advance."

        synthesizer = AVSpeechSynthesizer()
        synthesizer.delegate = self
        synthesizer.speak(buildUtterance(for: AVSpeechUtteranceDefaultSpeechRate, with: string))
    }
}
extension ViewController: AVSpeechSynthesizerDelegate {
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, willSpeakRangeOfSpeechString characterRange: NSRange, utterance: AVSpeechUtterance) {
        debugPrint(characterRange.toRange())
        currentRange = characterRange
    }
}
  1. реализовать метод делегата willSpeakRangeOfSpeechString из AVSpeechSynthesizerDelegate и определите делегат синтезатора как себя: synthesizer.delegate = self

  2. В этом методе делегата сохраните characterRange, о котором будет сказано далее.

  3. привязывать IBAction func sl(_ sender: UISlider) на событие вашего слайдера touchUpInside.

  4. в этом IBAction, прекратите говорить и получите подстроку вашего текущего текста, произнесенную из индекса, он бы продолжил.

  5. Создайте новое высказывание и начните говорить на нем

  6. Прибыль.

Свифт 3

import UIKit
import AVFoundation     

class ViewController: UIViewController{

    @IBOutlet weak var sliderVolume: UISlider!  //for volume
    @IBOutlet weak var sliderRate: UISlider!    //for rate
    @IBOutlet weak var sliderPitch: UISlider!   //for pitch
    @IBOutlet weak var txtForSpeak: UITextField!

    let speechSynth = AVSpeechSynthesizer()

    @IBAction func btnStartToSpeak(_ sender: UIButton) {

        let speechUtt = AVSpeechUtterance(string: self.txtForSpeak.text!)

            speechUtt.rate = self.sliderRate.value

            speechUtt.volume = self.sliderVolume.value

            speechUtt.pitchMultiplier = self.sliderPitch.value

        self.speechSynth.speak(speechUtt)
    }
}
Другие вопросы по тегам