Skip to content

[BUG] macOS: synthesizeToFile Ignores Selected Voice #606

@YofarDev

Description

@YofarDev

🐛 Bug Report

On macOS, the synthesizeToFile method does not use the voice set via setVoice. It always synthesizes the audio file using the default system voice. In contrast, the speak method works correctly and uses the selected voice.

Proposed Solution

This fix works for me. Code change in macos/Classes/FlutterTtsPlugin.swift:

// macos/Classes/FlutterTtsPlugin.swift

private func synthesizeToFile(text: String, fileName: String, result: @escaping FlutterResult) {
    var output: AVAudioFile?
    var failed = false
    let utterance = AVSpeechUtterance(string: text)

    // Add this block to apply the selected voice
    if self.voice != nil {
      utterance.voice = self.voice!
    } else {
      utterance.voice = AVSpeechSynthesisVoice(language: self.language)
    }

    if #available(iOS 13.0, *) { // This check should likely be macOS specific, e.g., macOS 10.15
      self.synthesizer.write(utterance) { (buffer: AVAudioBuffer) in
        guard let pcmBuffer = buffer as? AVAudioPCMBuffer else {
            NSLog("unknown buffer type: \(buffer)")
            failed = true
            return
        }
        if pcmBuffer.frameLength == 0 {
            // finished
        } else {
          // append buffer to file
          let fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent(fileName)
          NSLog("Saving utterance to file: \(fileURL.absoluteString)")

          if output == nil {
            do {
              output = try AVAudioFile(
              forWriting: fileURL,
              settings: pcmBuffer.format.settings,
              commonFormat: .pcmFormatFloat32,
              interleaved: false)
            } catch {
                NSLog(error.localizedDescription)
                failed = true
                return
            }
          }

          try! output!.write(from: pcmBuffer)
        }
      }
    } else {
        result("Unsupported macOS version")
    }
    if failed {
        result(0)
    }
    if self.awaitSynthCompletion {
      self.synthResult = result
    } else {
      result(1)
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions